i40e: new poll mode driver
Signed-off-by: Helin Zhang <helin.zhang@intel.com> Signed-off-by: Jing Chen <jing.d.chen@intel.com> Acked-by: Cunming Liang <cunming.liang@intel.com> Acked-by: Jijiang Liu <jijiang.liu@intel.com> Acked-by: Jingjing Wu <jingjing.wu@intel.com> Acked-by: Heqing Zhu <heqing.zhu@intel.com> Tested-by: Waterman Cao <waterman.cao@intel.com>
This commit is contained in:
parent
8db9e2a1b2
commit
4861cde461
@ -166,6 +166,23 @@ CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=n
|
||||
CONFIG_RTE_IXGBE_INC_VECTOR=n
|
||||
CONFIG_RTE_IXGBE_RX_OLFLAGS_DISABLE=n
|
||||
|
||||
#
|
||||
# Compile burst-oriented I40E PMD driver
|
||||
#
|
||||
CONFIG_RTE_LIBRTE_I40E_PMD=y
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=y
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=y
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=y
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=y
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=y
|
||||
CONFIG_RTE_LIBRTE_I40E_PF_DISABLE_STRIP_CRC=y
|
||||
CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=n
|
||||
CONFIG_RTE_LIBRTE_I40E_ALLOW_UNSUPPORTED_SFP=y
|
||||
CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
|
||||
CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
|
||||
# interval up to 8160 us, aligned to 2 (or default value)
|
||||
CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
|
||||
|
||||
#
|
||||
# Compile burst-oriented VIRTIO PMD driver
|
||||
#
|
||||
|
@ -194,6 +194,23 @@ CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=n
|
||||
CONFIG_RTE_IXGBE_INC_VECTOR=y
|
||||
CONFIG_RTE_IXGBE_RX_OLFLAGS_DISABLE=n
|
||||
|
||||
#
|
||||
# Compile burst-oriented I40E PMD driver
|
||||
#
|
||||
CONFIG_RTE_LIBRTE_I40E_PMD=y
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_INIT=n
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_RX=n
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
|
||||
CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
|
||||
CONFIG_RTE_LIBRTE_I40E_PF_DISABLE_STRIP_CRC=n
|
||||
CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
|
||||
CONFIG_RTE_LIBRTE_I40E_ALLOW_UNSUPPORTED_SFP=n
|
||||
CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
|
||||
CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4
|
||||
# interval up to 8160 us, aligned to 2 (or default value)
|
||||
CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1
|
||||
|
||||
#
|
||||
# Compile burst-oriented VIRTIO PMD driver
|
||||
#
|
||||
|
@ -43,6 +43,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += librte_pmd_e1000
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += librte_pmd_ixgbe
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += librte_pmd_i40e
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += librte_pmd_ring
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
|
||||
|
85
lib/librte_pmd_i40e/Makefile
Normal file
85
lib/librte_pmd_i40e/Makefile
Normal file
@ -0,0 +1,85 @@
|
||||
# BSD LICENSE
|
||||
#
|
||||
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
|
||||
# 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.
|
||||
|
||||
include $(RTE_SDK)/mk/rte.vars.mk
|
||||
|
||||
#
|
||||
# library name
|
||||
#
|
||||
LIB = librte_pmd_i40e.a
|
||||
|
||||
CFLAGS += -O3
|
||||
CFLAGS += $(WERROR_FLAGS)
|
||||
|
||||
ifeq ($(CC), icc)
|
||||
CFLAGS_SHARED_DRIVERS = -wd593
|
||||
else
|
||||
CFLAGS_SHARED_DRIVERS = -Wno-unused-but-set-variable
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-sign-compare
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-unused-value
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-unused-parameter
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-strict-aliasing
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-format
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-missing-field-initializers
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-pointer-to-int-cast
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-format-nonliteral
|
||||
CFLAGS_SHARED_DRIVERS += -Wno-format-security
|
||||
endif
|
||||
|
||||
#
|
||||
# Add extra flags for ND source files to disable warnings
|
||||
#
|
||||
SHARED_DRIVERS_OBJS=$(patsubst %.c,%.o,$(notdir $(wildcard $(RTE_SDK)/lib/librte_pmd_i40e/i40e/*.c)))
|
||||
$(foreach obj, $(SHARED_DRIVERS_OBJS), $(eval CFLAGS_$(obj)+=$(CFLAGS_SHARED_DRIVERS)))
|
||||
|
||||
VPATH += $(RTE_SDK)/lib/librte_pmd_i40e/i40e
|
||||
|
||||
#
|
||||
# all source are stored in SRCS-y
|
||||
#
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_adminq.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_common.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_diag.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_hmc.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_lan_hmc.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_nvm.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_dcb.c
|
||||
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_rxtx.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev_vf.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_pf.c
|
||||
# this lib depends upon:
|
||||
DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_eal lib/librte_ether
|
||||
DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_mempool lib/librte_mbuf
|
||||
DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_net lib/librte_malloc
|
||||
|
||||
include $(RTE_SDK)/mk/rte.lib.mk
|
197
lib/librte_pmd_i40e/i40e/i40e_osdep.h
Normal file
197
lib/librte_pmd_i40e/i40e/i40e_osdep.h
Normal file
@ -0,0 +1,197 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2014, 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:
|
||||
|
||||
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.
|
||||
|
||||
3. Neither the name of the 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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _I40E_OSDEP_H_
|
||||
#define _I40E_OSDEP_H_
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <rte_common.h>
|
||||
#include <rte_memcpy.h>
|
||||
#include <rte_byteorder.h>
|
||||
#include <rte_cycles.h>
|
||||
#include <rte_spinlock.h>
|
||||
#include <rte_log.h>
|
||||
|
||||
#include "../i40e_logs.h"
|
||||
|
||||
#define INLINE inline
|
||||
#define STATIC static
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef int8_t s8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef int32_t s32;
|
||||
typedef uint64_t u64;
|
||||
typedef int bool;
|
||||
|
||||
typedef enum i40e_status_code i40e_status;
|
||||
#define __iomem
|
||||
#define hw_dbg(hw, S, A...) do {} while (0)
|
||||
#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
|
||||
#define lower_32_bits(n) ((u32)(n))
|
||||
#define low_16_bits(x) ((x) & 0xFFFF)
|
||||
#define high_16_bits(x) (((x) & 0xFFFF0000) >> 16)
|
||||
|
||||
#ifndef ETH_ADDR_LEN
|
||||
#define ETH_ADDR_LEN 6
|
||||
#endif
|
||||
|
||||
#ifndef __le16
|
||||
#define __le16 uint16_t
|
||||
#endif
|
||||
#ifndef __le32
|
||||
#define __le32 uint32_t
|
||||
#endif
|
||||
#ifndef __le64
|
||||
#define __le64 uint64_t
|
||||
#endif
|
||||
#ifndef __be16
|
||||
#define __be16 uint16_t
|
||||
#endif
|
||||
#ifndef __be32
|
||||
#define __be32 uint32_t
|
||||
#endif
|
||||
#ifndef __be64
|
||||
#define __be64 uint64_t
|
||||
#endif
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
#define min(a,b) RTE_MIN(a,b)
|
||||
#define max(a,b) RTE_MAX(a,b)
|
||||
|
||||
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
|
||||
#define ASSERT(x) if(!(x)) rte_panic("IXGBE: x")
|
||||
|
||||
#define DEBUGOUT(S) PMD_DRV_LOG(DEBUG, S)
|
||||
#define DEBUGOUT1(S, A...) PMD_DRV_LOG(DEBUG, S, ##A)
|
||||
|
||||
#define DEBUGFUNC(F) DEBUGOUT(F)
|
||||
#define DEBUGOUT2 DEBUGOUT1
|
||||
#define DEBUGOUT3 DEBUGOUT2
|
||||
#define DEBUGOUT6 DEBUGOUT3
|
||||
#define DEBUGOUT7 DEBUGOUT6
|
||||
|
||||
#define i40e_debug(h, m, s, ...) \
|
||||
do { \
|
||||
if (((m) & (h)->debug_mask)) \
|
||||
PMD_DRV_LOG(DEBUG, "i40e %02x.%x " s, \
|
||||
(h)->bus.device, (h)->bus.func, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define I40E_PCI_REG(reg) (*((volatile uint32_t *)(reg)))
|
||||
#define I40E_PCI_REG_ADDR(a, reg) \
|
||||
((volatile uint32_t *)((char *)(a)->hw_addr + (reg)))
|
||||
static inline uint32_t i40e_read_addr(volatile void *addr)
|
||||
{
|
||||
return I40E_PCI_REG(addr);
|
||||
}
|
||||
#define I40E_PCI_REG_WRITE(reg, value) \
|
||||
do {I40E_PCI_REG((reg)) = (value);} while(0)
|
||||
|
||||
#define I40E_WRITE_FLUSH(a) I40E_READ_REG(a, I40E_GLGEN_STAT)
|
||||
#define I40EVF_WRITE_FLUSH(a) I40E_READ_REG(a, I40E_VFGEN_RSTAT)
|
||||
|
||||
#define I40E_READ_REG(hw, reg) i40e_read_addr(I40E_PCI_REG_ADDR((hw), (reg)))
|
||||
#define I40E_WRITE_REG(hw, reg, value) \
|
||||
I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), (reg)), (value))
|
||||
|
||||
#define rd32(a, reg) i40e_read_addr(I40E_PCI_REG_ADDR((a), (reg)))
|
||||
#define wr32(a, reg, value) \
|
||||
I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value))
|
||||
#define flush(a) i40e_read_addr(I40E_PCI_REG_ADDR((a), (I40E_GLGEN_STAT)))
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
/* memory allocation tracking */
|
||||
struct i40e_dma_mem {
|
||||
void *va;
|
||||
u64 pa;
|
||||
u32 size;
|
||||
u64 id;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define i40e_allocate_dma_mem(h, m, unused, s, a) \
|
||||
i40e_allocate_dma_mem_d(h, m, s, a)
|
||||
#define i40e_free_dma_mem(h, m) i40e_free_dma_mem_d(h, m)
|
||||
|
||||
struct i40e_virt_mem {
|
||||
void *va;
|
||||
u32 size;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define i40e_allocate_virt_mem(h, m, s) i40e_allocate_virt_mem_d(h, m, s)
|
||||
#define i40e_free_virt_mem(h, m) i40e_free_virt_mem_d(h, m)
|
||||
|
||||
#define CPU_TO_LE16(o) rte_cpu_to_le_16(o)
|
||||
#define CPU_TO_LE32(s) rte_cpu_to_le_32(s)
|
||||
#define CPU_TO_LE64(h) rte_cpu_to_le_64(h)
|
||||
#define LE16_TO_CPU(a) rte_le_to_cpu_16(a)
|
||||
#define LE32_TO_CPU(c) rte_le_to_cpu_32(c)
|
||||
#define LE64_TO_CPU(k) rte_le_to_cpu_64(k)
|
||||
|
||||
/* SW spinlock */
|
||||
struct i40e_spinlock {
|
||||
rte_spinlock_t spinlock;
|
||||
};
|
||||
|
||||
#define i40e_init_spinlock(_sp) i40e_init_spinlock_d(_sp)
|
||||
#define i40e_acquire_spinlock(_sp) i40e_acquire_spinlock_d(_sp)
|
||||
#define i40e_release_spinlock(_sp) i40e_release_spinlock_d(_sp)
|
||||
#define i40e_destroy_spinlock(_sp) i40e_destroy_spinlock_d(_sp)
|
||||
|
||||
#define I40E_NTOHS(a) rte_be_to_cpu_16(a)
|
||||
#define I40E_NTOHL(a) rte_be_to_cpu_32(a)
|
||||
#define I40E_HTONS(a) rte_cpu_to_be_16(a)
|
||||
#define I40E_HTONL(a) rte_cpu_to_be_32(a)
|
||||
|
||||
#define i40e_memset(a, b, c, d) memset((a), (b), (c))
|
||||
#define i40e_memcpy(a, b, c, d) rte_memcpy((a), (b), (c))
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
#define DELAY(x) rte_delay_us(x)
|
||||
#define i40e_usec_delay(x) rte_delay_us(x)
|
||||
#define i40e_msec_delay(x) rte_delay_us(1000*(x))
|
||||
#define udelay(x) DELAY(x)
|
||||
#define msleep(x) DELAY(1000*(x))
|
||||
#define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000))
|
||||
|
||||
#endif /* _I40E_OSDEP_H_ */
|
4019
lib/librte_pmd_i40e/i40e_ethdev.c
Normal file
4019
lib/librte_pmd_i40e/i40e_ethdev.c
Normal file
File diff suppressed because it is too large
Load Diff
356
lib/librte_pmd_i40e/i40e_ethdev.h
Normal file
356
lib/librte_pmd_i40e/i40e_ethdev.h
Normal file
@ -0,0 +1,356 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _I40E_ETHDEV_H_
|
||||
#define _I40E_ETHDEV_H_
|
||||
|
||||
#define I40E_AQ_LEN 32
|
||||
#define I40E_AQ_BUF_SZ 4096
|
||||
/* Number of queues per TC should be one of 1, 2, 4, 8, 16, 32, 64 */
|
||||
#define I40E_MAX_Q_PER_TC 64
|
||||
#define I40E_NUM_DESC_DEFAULT 512
|
||||
#define I40E_NUM_DESC_ALIGN 32
|
||||
#define I40E_BUF_SIZE_MIN 1024
|
||||
#define I40E_FRAME_SIZE_MAX 9728
|
||||
#define I40E_QUEUE_BASE_ADDR_UNIT 128
|
||||
/* number of VSIs and queue default setting */
|
||||
#define I40E_MAX_QP_NUM_PER_VF 16
|
||||
#define I40E_DEFAULT_QP_NUM_VMDQ 64
|
||||
#define I40E_DEFAULT_QP_NUM_FDIR 64
|
||||
#define I40E_UINT32_BIT_SIZE (CHAR_BIT * sizeof(uint32_t))
|
||||
#define I40E_VFTA_SIZE (4096 / I40E_UINT32_BIT_SIZE)
|
||||
/* Default TC traffic in case DCB is not enabled */
|
||||
#define I40E_DEFAULT_TCMAP 0x1
|
||||
|
||||
/* i40e flags */
|
||||
#define I40E_FLAG_RSS (1ULL << 0)
|
||||
#define I40E_FLAG_DCB (1ULL << 1)
|
||||
#define I40E_FLAG_VMDQ (1ULL << 2)
|
||||
#define I40E_FLAG_SRIOV (1ULL << 3)
|
||||
#define I40E_FLAG_HEADER_SPLIT_DISABLED (1ULL << 4)
|
||||
#define I40E_FLAG_HEADER_SPLIT_ENABLED (1ULL << 5)
|
||||
#define I40E_FLAG_FDIR (1ULL << 6)
|
||||
#define I40E_FLAG_ALL (I40E_FLAG_RSS | \
|
||||
I40E_FLAG_DCB | \
|
||||
I40E_FLAG_VMDQ | \
|
||||
I40E_FLAG_SRIOV | \
|
||||
I40E_FLAG_HEADER_SPLIT_DISABLED | \
|
||||
I40E_FLAG_HEADER_SPLIT_ENABLED | \
|
||||
I40E_FLAG_FDIR)
|
||||
|
||||
struct i40e_adapter;
|
||||
|
||||
TAILQ_HEAD(i40e_mac_filter_list, i40e_mac_filter);
|
||||
|
||||
/* MAC filter list structure */
|
||||
struct i40e_mac_filter {
|
||||
TAILQ_ENTRY(i40e_mac_filter) next;
|
||||
struct ether_addr macaddr;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(i40e_vsi_list_head, i40e_vsi_list);
|
||||
|
||||
struct i40e_vsi;
|
||||
|
||||
/* VSI list structure */
|
||||
struct i40e_vsi_list {
|
||||
TAILQ_ENTRY(i40e_vsi_list) list;
|
||||
struct i40e_vsi *vsi;
|
||||
};
|
||||
|
||||
struct i40e_rx_queue;
|
||||
struct i40e_tx_queue;
|
||||
|
||||
/* Structure that defines a VEB */
|
||||
struct i40e_veb {
|
||||
struct i40e_vsi_list_head head;
|
||||
struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
|
||||
uint16_t seid; /* The seid of VEB itself */
|
||||
uint16_t uplink_seid; /* The uplink seid of this VEB */
|
||||
uint16_t stats_idx;
|
||||
struct i40e_eth_stats stats;
|
||||
};
|
||||
|
||||
/* MACVLAN filter structure */
|
||||
struct i40e_macvlan_filter {
|
||||
struct ether_addr macaddr;
|
||||
uint16_t vlan_id;
|
||||
};
|
||||
/*
|
||||
* Structure that defines a VSI, associated with a adapter.
|
||||
*/
|
||||
struct i40e_vsi {
|
||||
struct i40e_adapter *adapter; /* Backreference to associated adapter */
|
||||
struct i40e_aqc_vsi_properties_data info; /* VSI properties */
|
||||
|
||||
struct i40e_eth_stats eth_stats_offset;
|
||||
struct i40e_eth_stats eth_stats;
|
||||
/*
|
||||
* When drivers loaded, only a default main VSI exists. In case new VSI
|
||||
* needs to add, HW needs to know the layout that VSIs are organized.
|
||||
* Besides that, VSI isan element and can't switch packets, which needs
|
||||
* to add new component VEB to perform switching. So, a new VSI needs
|
||||
* to specify the the uplink VSI (Parent VSI) before created. The
|
||||
* uplink VSI will check whether it had a VEB to switch packets. If no,
|
||||
* it will try to create one. Then, uplink VSI will move the new VSI
|
||||
* into its' sib_vsi_list to manage all the downlink VSI.
|
||||
* sib_vsi_list: the VSI list that shared the same uplink VSI.
|
||||
* parent_vsi : the uplink VSI. It's NULL for main VSI.
|
||||
* veb : the VEB associates with the VSI.
|
||||
*/
|
||||
struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
|
||||
struct i40e_vsi *parent_vsi;
|
||||
struct i40e_veb *veb; /* Associated veb, could be null */
|
||||
bool offset_loaded;
|
||||
enum i40e_vsi_type type; /* VSI types */
|
||||
uint16_t vlan_num; /* Total VLAN number */
|
||||
uint16_t mac_num; /* Total mac number */
|
||||
uint32_t vfta[I40E_VFTA_SIZE]; /* VLAN bitmap */
|
||||
struct i40e_mac_filter_list mac_list; /* macvlan filter list */
|
||||
/* specific VSI-defined parameters, SRIOV stored the vf_id */
|
||||
uint32_t user_param;
|
||||
uint16_t seid; /* The seid of VSI itself */
|
||||
uint16_t uplink_seid; /* The uplink seid of this VSI */
|
||||
uint16_t nb_qps; /* Number of queue pairs VSI can occupy */
|
||||
uint16_t max_macaddrs; /* Maximum number of MAC addresses */
|
||||
uint16_t base_queue; /* The first queue index of this VSI */
|
||||
/*
|
||||
* The offset to visit VSI related register, assigned by HW when
|
||||
* creating VSI
|
||||
*/
|
||||
uint16_t vsi_id;
|
||||
uint16_t msix_intr; /* The MSIX interrupt binds to VSI */
|
||||
uint8_t enabled_tc; /* The traffic class enabled */
|
||||
};
|
||||
|
||||
struct pool_entry {
|
||||
LIST_ENTRY(pool_entry) next;
|
||||
uint16_t base;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
LIST_HEAD(res_list, pool_entry);
|
||||
|
||||
struct i40e_res_pool_info {
|
||||
uint32_t base; /* Resource start index */
|
||||
uint32_t num_alloc; /* Allocated resource number */
|
||||
uint32_t num_free; /* Total available resource number */
|
||||
struct res_list alloc_list; /* Allocated resource list */
|
||||
struct res_list free_list; /* Available resource list */
|
||||
};
|
||||
|
||||
enum I40E_VF_STATE {
|
||||
I40E_VF_INACTIVE = 0,
|
||||
I40E_VF_INRESET,
|
||||
I40E_VF_ININIT,
|
||||
I40E_VF_ACTIVE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to store private data for PF host.
|
||||
*/
|
||||
struct i40e_pf_vf {
|
||||
struct i40e_pf *pf;
|
||||
struct i40e_vsi *vsi;
|
||||
enum I40E_VF_STATE state; /* The number of queue pairs availiable */
|
||||
uint16_t vf_idx; /* VF index in pf->vfs */
|
||||
uint16_t lan_nb_qps; /* Actual queues allocated */
|
||||
uint16_t reset_cnt; /* Total vf reset times */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to store private data specific for PF instance.
|
||||
*/
|
||||
struct i40e_pf {
|
||||
struct i40e_adapter *adapter; /* The adapter this PF associate to */
|
||||
struct i40e_vsi *main_vsi; /* pointer to main VSI structure */
|
||||
uint16_t mac_seid; /* The seid of the MAC of this PF */
|
||||
uint16_t main_vsi_seid; /* The seid of the main VSI */
|
||||
uint16_t max_num_vsi;
|
||||
struct i40e_res_pool_info qp_pool; /*Queue pair pool */
|
||||
struct i40e_res_pool_info msix_pool; /* MSIX interrupt pool */
|
||||
|
||||
struct i40e_hw_port_stats stats_offset;
|
||||
struct i40e_hw_port_stats stats;
|
||||
bool offset_loaded;
|
||||
|
||||
struct rte_eth_dev_data *dev_data; /* Pointer to the device data */
|
||||
struct ether_addr dev_addr; /* PF device mac address */
|
||||
uint64_t flags; /* PF featuer flags */
|
||||
/* All kinds of queue pair setting for different VSIs */
|
||||
struct i40e_pf_vf *vfs;
|
||||
uint16_t vf_num;
|
||||
/* Each of below queue pairs should be power of 2 since it's the
|
||||
precondition after TC configuration applied */
|
||||
uint16_t lan_nb_qps; /* The number of queue pairs of LAN */
|
||||
uint16_t vmdq_nb_qps; /* The number of queue pairs of VMDq */
|
||||
uint16_t vf_nb_qps; /* The number of queue pairs of VF */
|
||||
uint16_t fdir_nb_qps; /* The number of queue pairs of Flow Director */
|
||||
};
|
||||
|
||||
enum pending_msg {
|
||||
PFMSG_LINK_CHANGE = 0x1,
|
||||
PFMSG_RESET_IMPENDING = 0x2,
|
||||
PFMSG_DRIVER_CLOSE = 0x4,
|
||||
};
|
||||
|
||||
struct i40e_vf_rx_queues {
|
||||
uint64_t rx_dma_addr;
|
||||
uint32_t rx_ring_len;
|
||||
uint32_t buff_size;
|
||||
};
|
||||
|
||||
struct i40e_vf_tx_queues {
|
||||
uint64_t tx_dma_addr;
|
||||
uint32_t tx_ring_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to store private data specific for VF instance.
|
||||
*/
|
||||
struct i40e_vf {
|
||||
uint16_t num_queue_pairs;
|
||||
uint16_t max_pkt_len; /* Maximum packet length */
|
||||
bool promisc_unicast_enabled;
|
||||
bool promisc_multicast_enabled;
|
||||
|
||||
bool host_is_dpdk; /* The flag indicates if the host is DPDK */
|
||||
uint16_t promisc_flags; /* Promiscuous setting */
|
||||
uint32_t vlan[I40E_VFTA_SIZE]; /* VLAN bit map */
|
||||
|
||||
/* Event from pf */
|
||||
bool dev_closed;
|
||||
bool link_up;
|
||||
bool vf_reset;
|
||||
volatile uint32_t pend_cmd; /* pending command not finished yet */
|
||||
u16 pend_msg; /* flags indicates events from pf not handled yet */
|
||||
|
||||
/* VSI info */
|
||||
struct i40e_virtchnl_vf_resource *vf_res; /* All VSIs */
|
||||
struct i40e_virtchnl_vsi_resource *vsi_res; /* LAN VSI */
|
||||
struct i40e_vsi vsi;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to store private data for each PF/VF instance.
|
||||
*/
|
||||
struct i40e_adapter {
|
||||
/* Common for both PF and VF */
|
||||
struct i40e_hw hw;
|
||||
struct rte_eth_dev *eth_dev;
|
||||
|
||||
/* Specific for PF or VF */
|
||||
union {
|
||||
struct i40e_pf pf;
|
||||
struct i40e_vf vf;
|
||||
};
|
||||
};
|
||||
|
||||
int i40e_vsi_switch_queues(struct i40e_vsi *vsi, bool on);
|
||||
int i40e_vsi_release(struct i40e_vsi *vsi);
|
||||
struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
|
||||
enum i40e_vsi_type type,
|
||||
struct i40e_vsi *uplink_vsi,
|
||||
uint16_t user_param);
|
||||
int i40e_switch_rx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on);
|
||||
int i40e_switch_tx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on);
|
||||
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, uint16_t vlan);
|
||||
int i40e_vsi_delete_vlan(struct i40e_vsi *vsi, uint16_t vlan);
|
||||
int i40e_vsi_add_mac(struct i40e_vsi *vsi, struct ether_addr *addr);
|
||||
int i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr);
|
||||
void i40e_update_vsi_stats(struct i40e_vsi *vsi);
|
||||
void i40e_pf_disable_irq0(struct i40e_hw *hw);
|
||||
void i40e_pf_enable_irq0(struct i40e_hw *hw);
|
||||
int i40e_dev_link_update(struct rte_eth_dev *dev,
|
||||
__rte_unused int wait_to_complete);
|
||||
void i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi);
|
||||
void i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi);
|
||||
|
||||
/* I40E_DEV_PRIVATE_TO */
|
||||
#define I40E_DEV_PRIVATE_TO_PF(adapter) \
|
||||
(&((struct i40e_adapter *)adapter)->pf)
|
||||
#define I40E_DEV_PRIVATE_TO_HW(adapter) \
|
||||
(&((struct i40e_adapter *)adapter)->hw)
|
||||
#define I40E_DEV_PRIVATE_TO_ADAPTER(adapter) \
|
||||
((struct i40e_adapter *)adapter)
|
||||
|
||||
/* I40EVF_DEV_PRIVATE_TO */
|
||||
#define I40EVF_DEV_PRIVATE_TO_VF(adapter) \
|
||||
(&((struct i40e_adapter *)adapter)->vf)
|
||||
|
||||
static inline struct i40e_vsi *
|
||||
i40e_get_vsi_from_adapter(struct i40e_adapter *adapter)
|
||||
{
|
||||
struct i40e_hw *hw;
|
||||
|
||||
if (!adapter)
|
||||
return NULL;
|
||||
|
||||
hw = I40E_DEV_PRIVATE_TO_HW(adapter);
|
||||
if (hw->mac.type == I40E_MAC_VF) {
|
||||
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(adapter);
|
||||
return &vf->vsi;
|
||||
} else {
|
||||
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(adapter);
|
||||
return pf->main_vsi;
|
||||
}
|
||||
}
|
||||
#define I40E_DEV_PRIVATE_TO_VSI(adapter) \
|
||||
i40e_get_vsi_from_adapter((struct i40e_adapter *)adapter)
|
||||
|
||||
/* I40E_VSI_TO */
|
||||
#define I40E_VSI_TO_HW(vsi) \
|
||||
(&(((struct i40e_vsi *)vsi)->adapter->hw))
|
||||
#define I40E_VSI_TO_PF(vsi) \
|
||||
(&(((struct i40e_vsi *)vsi)->adapter->pf))
|
||||
#define I40E_VSI_TO_DEV_DATA(vsi) \
|
||||
(((struct i40e_vsi *)vsi)->adapter->pf.dev_data)
|
||||
#define I40E_VSI_TO_ETH_DEV(vsi) \
|
||||
(((struct i40e_vsi *)vsi)->adapter->eth_dev)
|
||||
|
||||
/* I40E_PF_TO */
|
||||
#define I40E_PF_TO_HW(pf) \
|
||||
(&(((struct i40e_pf *)pf)->adapter->hw))
|
||||
#define I40E_PF_TO_ADAPTER(pf) \
|
||||
((struct i40e_adapter *)pf->adapter)
|
||||
|
||||
static inline void
|
||||
i40e_init_adminq_parameter(struct i40e_hw *hw)
|
||||
{
|
||||
hw->aq.num_arq_entries = I40E_AQ_LEN;
|
||||
hw->aq.num_asq_entries = I40E_AQ_LEN;
|
||||
hw->aq.arq_buf_size = I40E_AQ_BUF_SZ;
|
||||
hw->aq.asq_buf_size = I40E_AQ_BUF_SZ;
|
||||
}
|
||||
|
||||
#endif /* _I40E_ETHDEV_H_ */
|
1336
lib/librte_pmd_i40e/i40e_ethdev_vf.c
Normal file
1336
lib/librte_pmd_i40e/i40e_ethdev_vf.c
Normal file
File diff suppressed because it is too large
Load Diff
74
lib/librte_pmd_i40e/i40e_logs.h
Normal file
74
lib/librte_pmd_i40e/i40e_logs.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _I40E_LOGS_H_
|
||||
#define _I40E_LOGS_H_
|
||||
|
||||
#ifdef RTE_LIBRTE_I40E_DEBUG_INIT
|
||||
#define PMD_INIT_LOG(level, fmt, args...) \
|
||||
RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
|
||||
#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
|
||||
#else
|
||||
#define PMD_INIT_LOG(level, fmt, args...) do { } while(0)
|
||||
#define PMD_INIT_FUNC_TRACE() do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifdef RTE_LIBRTE_I40E_DEBUG_RX
|
||||
#define PMD_RX_LOG(level, fmt, args...) \
|
||||
RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
|
||||
#else
|
||||
#define PMD_RX_LOG(level, fmt, args...) do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifdef RTE_LIBRTE_I40E_DEBUG_TX
|
||||
#define PMD_TX_LOG(level, fmt, args...) \
|
||||
RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
|
||||
#else
|
||||
#define PMD_TX_LOG(level, fmt, args...) do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifdef RTE_LIBRTE_I40E_DEBUG_TX_FREE
|
||||
#define PMD_TX_FREE_LOG(level, fmt, args...) \
|
||||
RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
|
||||
#else
|
||||
#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifdef RTE_LIBRTE_I40E_DEBUG_DRIVER
|
||||
#define PMD_DRV_LOG(level, fmt, args...) \
|
||||
RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
|
||||
#else
|
||||
#define PMD_DRV_LOG(level, fmt, args...) do { } while(0)
|
||||
#endif
|
||||
|
||||
#endif /* _I40E_LOGS_H_ */
|
928
lib/librte_pmd_i40e/i40e_pf.c
Normal file
928
lib/librte_pmd_i40e/i40e_pf.c
Normal file
@ -0,0 +1,928 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <rte_string_fns.h>
|
||||
#include <rte_pci.h>
|
||||
#include <rte_ether.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_memzone.h>
|
||||
#include <rte_malloc.h>
|
||||
#include <rte_memcpy.h>
|
||||
|
||||
#include "i40e_logs.h"
|
||||
#include "i40e/i40e_prototype.h"
|
||||
#include "i40e/i40e_adminq_cmd.h"
|
||||
#include "i40e/i40e_type.h"
|
||||
#include "i40e_ethdev.h"
|
||||
#include "i40e_rxtx.h"
|
||||
#include "i40e_pf.h"
|
||||
|
||||
static int
|
||||
i40e_pf_host_switch_queues(struct i40e_pf_vf *vf,
|
||||
struct i40e_virtchnl_queue_select *qsel,
|
||||
bool on);
|
||||
|
||||
/**
|
||||
* Bind PF queues with VSI and VF.
|
||||
**/
|
||||
static int
|
||||
i40e_pf_vf_queues_mapping(struct i40e_pf_vf *vf)
|
||||
{
|
||||
int i;
|
||||
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
|
||||
uint16_t vsi_id = vf->vsi->vsi_id;
|
||||
uint16_t vf_id = vf->vf_idx;
|
||||
uint16_t nb_qps = vf->vsi->nb_qps;
|
||||
uint16_t qbase = vf->vsi->base_queue;
|
||||
uint16_t q1, q2;
|
||||
uint32_t val;
|
||||
|
||||
/*
|
||||
* VF should use scatter range queues. So, it needn't
|
||||
* to set QBASE in this register.
|
||||
*/
|
||||
I40E_WRITE_REG(hw, I40E_VSILAN_QBASE(vsi_id),
|
||||
I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK);
|
||||
|
||||
/* Set to enable VFLAN_QTABLE[] registers valid */
|
||||
I40E_WRITE_REG(hw, I40E_VPLAN_MAPENA(vf_id),
|
||||
I40E_VPLAN_MAPENA_TXRX_ENA_MASK);
|
||||
|
||||
/* map PF queues to VF */
|
||||
for (i = 0; i < nb_qps; i++) {
|
||||
val = ((qbase + i) & I40E_VPLAN_QTABLE_QINDEX_MASK);
|
||||
I40E_WRITE_REG(hw, I40E_VPLAN_QTABLE(i, vf_id), val);
|
||||
}
|
||||
|
||||
/* map PF queues to VSI */
|
||||
for (i = 0; i < I40E_MAX_QP_NUM_PER_VF / 2; i++) {
|
||||
if (2 * i > nb_qps - 1)
|
||||
q1 = I40E_VSILAN_QTABLE_QINDEX_0_MASK;
|
||||
else
|
||||
q1 = qbase + 2 * i;
|
||||
|
||||
if (2 * i + 1 > nb_qps - 1)
|
||||
q2 = I40E_VSILAN_QTABLE_QINDEX_0_MASK;
|
||||
else
|
||||
q2 = qbase + 2 * i + 1;
|
||||
|
||||
val = (q2 << I40E_VSILAN_QTABLE_QINDEX_1_SHIFT) + q1;
|
||||
I40E_WRITE_REG(hw, I40E_VSILAN_QTABLE(i, vsi_id), val);
|
||||
}
|
||||
I40E_WRITE_FLUSH(hw);
|
||||
|
||||
return I40E_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Proceed VF reset operation.
|
||||
*/
|
||||
int
|
||||
i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
|
||||
{
|
||||
uint32_t val, i;
|
||||
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
|
||||
uint16_t vf_id, abs_vf_id, vf_msix_num;
|
||||
int ret;
|
||||
struct i40e_virtchnl_queue_select qsel;
|
||||
|
||||
if (vf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
vf_id = vf->vf_idx;
|
||||
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);
|
||||
|
||||
/*
|
||||
* If require a SW VF reset, a VFLR interrupt will be generated,
|
||||
* this function will be called again. To avoid it,
|
||||
* disable interrupt first.
|
||||
*/
|
||||
if (do_hw_reset) {
|
||||
vf->state = I40E_VF_INRESET;
|
||||
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);
|
||||
I40E_WRITE_FLUSH(hw);
|
||||
}
|
||||
|
||||
#define VFRESET_MAX_WAIT_CNT 100
|
||||
/* Wait until VF reset is done */
|
||||
for (i = 0; i < VFRESET_MAX_WAIT_CNT; i++) {
|
||||
rte_delay_us(10);
|
||||
val = I40E_READ_REG(hw, I40E_VPGEN_VFRSTAT(vf_id));
|
||||
if (val & I40E_VPGEN_VFRSTAT_VFRD_MASK)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= VFRESET_MAX_WAIT_CNT) {
|
||||
PMD_DRV_LOG(ERR, "VF reset timeout\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* This is not first time to do reset, do cleanup job first */
|
||||
if (vf->vsi) {
|
||||
/* Disable queues */
|
||||
memset(&qsel, 0, sizeof(qsel));
|
||||
for (i = 0; i < vf->vsi->nb_qps; i++)
|
||||
qsel.rx_queues |= 1 << i;
|
||||
qsel.tx_queues = qsel.rx_queues;
|
||||
ret = i40e_pf_host_switch_queues(vf, &qsel, false);
|
||||
if (ret != I40E_SUCCESS) {
|
||||
PMD_DRV_LOG(ERR, "Disable VF queues failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Disable VF interrupt setting */
|
||||
vf_msix_num = hw->func_caps.num_msix_vectors_vf;
|
||||
for (i = 0; i < vf_msix_num; i++) {
|
||||
if (!i)
|
||||
val = I40E_VFINT_DYN_CTL0(vf_id);
|
||||
else
|
||||
val = I40E_VFINT_DYN_CTLN(((vf_msix_num - 1) *
|
||||
(vf_id)) + (i - 1));
|
||||
I40E_WRITE_REG(hw, val, I40E_VFINT_DYN_CTLN_CLEARPBA_MASK);
|
||||
}
|
||||
I40E_WRITE_FLUSH(hw);
|
||||
|
||||
/* remove VSI */
|
||||
ret = i40e_vsi_release(vf->vsi);
|
||||
if (ret != I40E_SUCCESS) {
|
||||
PMD_DRV_LOG(ERR, "Release VSI failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
#define I40E_VF_PCI_ADDR 0xAA
|
||||
#define I40E_VF_PEND_MASK 0x20
|
||||
/* Check the pending transactions of this VF */
|
||||
/* Use absolute VF id, refer to datasheet for details */
|
||||
I40E_WRITE_REG(hw, I40E_PF_PCI_CIAA, I40E_VF_PCI_ADDR |
|
||||
(abs_vf_id << I40E_PF_PCI_CIAA_VF_NUM_SHIFT));
|
||||
for (i = 0; i < VFRESET_MAX_WAIT_CNT; i++) {
|
||||
rte_delay_us(1);
|
||||
val = I40E_READ_REG(hw, I40E_PF_PCI_CIAD);
|
||||
if ((val & I40E_VF_PEND_MASK) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= VFRESET_MAX_WAIT_CNT) {
|
||||
PMD_DRV_LOG(ERR, "Wait VF PCI transaction end timeout\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Reset done, Set COMPLETE flag and clear reset bit */
|
||||
I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_PF_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);
|
||||
vf->reset_cnt++;
|
||||
I40E_WRITE_FLUSH(hw);
|
||||
|
||||
/* Allocate resource again */
|
||||
vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
|
||||
vf->pf->main_vsi, vf->vf_idx);
|
||||
if (vf->vsi == NULL) {
|
||||
PMD_DRV_LOG(ERR, "Add vsi failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = i40e_pf_vf_queues_mapping(vf);
|
||||
if (ret != I40E_SUCCESS) {
|
||||
PMD_DRV_LOG(ERR, "queue mapping error\n");
|
||||
i40e_vsi_release(vf->vsi);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf,
|
||||
uint32_t opcode,
|
||||
uint32_t retval,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
|
||||
uint16_t abs_vf_id = hw->func_caps.vf_base_id + vf->vf_idx;
|
||||
int ret;
|
||||
|
||||
ret = i40e_aq_send_msg_to_vf(hw, abs_vf_id, opcode, retval,
|
||||
msg, msglen, NULL);
|
||||
if (ret) {
|
||||
PMD_DRV_LOG(ERR, "Fail to send message to VF, err %u\n",
|
||||
hw->aq.asq_last_status);
|
||||
printf("Fail to send message to VF, err %u\n",
|
||||
hw->aq.asq_last_status);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_reset_vf(struct i40e_pf_vf *vf)
|
||||
{
|
||||
i40e_pf_host_vf_reset(vf, 1);
|
||||
|
||||
/* No feedback will be sent to VF for VFLR */
|
||||
return I40E_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf)
|
||||
{
|
||||
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;
|
||||
|
||||
/* only have 1 VSI by default */
|
||||
len = sizeof(struct i40e_virtchnl_vf_resource) +
|
||||
I40E_DEFAULT_VF_VSI_NUM *
|
||||
sizeof(struct i40e_virtchnl_vsi_resource);
|
||||
|
||||
vf_res = rte_zmalloc("i40e_vf_res", len, 0);
|
||||
if (vf_res == NULL) {
|
||||
PMD_DRV_LOG(ERR, "failed to allocate mem\n");
|
||||
ret = I40E_ERR_NO_MEMORY;
|
||||
vf_res = NULL;
|
||||
len = 0;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
vf_res->vf_offload_flags = I40E_VIRTCHNL_VF_OFFLOAD_L2;
|
||||
vf_res->max_vectors = hw->func_caps.num_msix_vectors_vf;
|
||||
vf_res->num_queue_pairs = vf->vsi->nb_qps;
|
||||
vf_res->num_vsis = I40E_DEFAULT_VF_VSI_NUM;
|
||||
|
||||
/* Change below setting if PF host can support more VSIs for VF */
|
||||
vf_res->vsi_res[0].vsi_type = I40E_VSI_SRIOV;
|
||||
/* As assume Vf only has single VSI now, always return 0 */
|
||||
vf_res->vsi_res[0].vsi_id = 0;
|
||||
vf_res->vsi_res[0].num_queue_pairs = vf->vsi->nb_qps;
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
|
||||
ret, (uint8_t *)vf_res, len);
|
||||
rte_free(vf_res);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_hmc_config_rxq(struct i40e_hw *hw,
|
||||
struct i40e_pf_vf *vf,
|
||||
struct i40e_virtchnl_rxq_info *rxq)
|
||||
{
|
||||
int err = I40E_SUCCESS;
|
||||
struct i40e_hmc_obj_rxq rx_ctx;
|
||||
uint16_t abs_queue_id = vf->vsi->base_queue + rxq->queue_id;
|
||||
|
||||
/* Clear the context structure first */
|
||||
memset(&rx_ctx, 0, sizeof(struct i40e_hmc_obj_rxq));
|
||||
rx_ctx.dbuff = rxq->databuffer_size >> I40E_RXQ_CTX_DBUFF_SHIFT;
|
||||
rx_ctx.hbuff = rxq->hdr_size >> I40E_RXQ_CTX_HBUFF_SHIFT;
|
||||
rx_ctx.base = rxq->dma_ring_addr / I40E_QUEUE_BASE_ADDR_UNIT;
|
||||
rx_ctx.qlen = rxq->ring_len;
|
||||
#ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
|
||||
rx_ctx.dsize = 1;
|
||||
#endif
|
||||
|
||||
if (rxq->splithdr_enabled) {
|
||||
rx_ctx.hsplit_0 = I40E_HEADER_SPLIT_ALL;
|
||||
rx_ctx.dtype = i40e_header_split_enabled;
|
||||
} else {
|
||||
rx_ctx.hsplit_0 = I40E_HEADER_SPLIT_NONE;
|
||||
rx_ctx.dtype = i40e_header_split_none;
|
||||
}
|
||||
rx_ctx.rxmax = rxq->max_pkt_size;
|
||||
rx_ctx.tphrdesc_ena = 1;
|
||||
rx_ctx.tphwdesc_ena = 1;
|
||||
rx_ctx.tphdata_ena = 1;
|
||||
rx_ctx.tphhead_ena = 1;
|
||||
rx_ctx.lrxqthresh = 2;
|
||||
rx_ctx.crcstrip = 1;
|
||||
rx_ctx.prefena = 1;
|
||||
|
||||
err = i40e_clear_lan_rx_queue_context(hw, abs_queue_id);
|
||||
if (err != I40E_SUCCESS)
|
||||
return err;
|
||||
err = i40e_set_lan_rx_queue_context(hw, abs_queue_id, &rx_ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_hmc_config_txq(struct i40e_hw *hw,
|
||||
struct i40e_pf_vf *vf,
|
||||
struct i40e_virtchnl_txq_info *txq)
|
||||
{
|
||||
int err = I40E_SUCCESS;
|
||||
struct i40e_hmc_obj_txq tx_ctx;
|
||||
uint32_t qtx_ctl;
|
||||
uint16_t abs_queue_id = vf->vsi->base_queue + txq->queue_id;
|
||||
|
||||
|
||||
/* clear the context structure first */
|
||||
memset(&tx_ctx, 0, sizeof(tx_ctx));
|
||||
tx_ctx.new_context = 1;
|
||||
tx_ctx.base = txq->dma_ring_addr / I40E_QUEUE_BASE_ADDR_UNIT;
|
||||
tx_ctx.qlen = txq->ring_len;
|
||||
tx_ctx.rdylist = rte_le_to_cpu_16(vf->vsi->info.qs_handle[0]);
|
||||
err = i40e_clear_lan_tx_queue_context(hw, abs_queue_id);
|
||||
if (err != I40E_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = i40e_set_lan_tx_queue_context(hw, abs_queue_id, &tx_ctx);
|
||||
if (err != I40E_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* bind queue with VF function, since TX/QX will appear in pair,
|
||||
* so only has QTX_CTL to set.
|
||||
*/
|
||||
qtx_ctl = (I40E_QTX_CTL_VF_QUEUE << I40E_QTX_CTL_PFVF_Q_SHIFT) |
|
||||
((hw->pf_id << I40E_QTX_CTL_PF_INDX_SHIFT) &
|
||||
I40E_QTX_CTL_PF_INDX_MASK) |
|
||||
(((vf->vf_idx + hw->func_caps.vf_base_id) <<
|
||||
I40E_QTX_CTL_VFVM_INDX_SHIFT) &
|
||||
I40E_QTX_CTL_VFVM_INDX_MASK);
|
||||
I40E_WRITE_REG(hw, I40E_QTX_CTL(abs_queue_id), qtx_ctl);
|
||||
I40E_WRITE_FLUSH(hw);
|
||||
|
||||
return I40E_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_config_vsi_queues(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
|
||||
struct i40e_vsi *vsi = vf->vsi;
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_vsi_queue_config_info *qconfig =
|
||||
(struct i40e_virtchnl_vsi_queue_config_info *)msg;
|
||||
int i;
|
||||
struct i40e_virtchnl_queue_pair_info *qpair;
|
||||
|
||||
if (msglen <= sizeof(*qconfig) ||
|
||||
qconfig->num_queue_pairs > vsi->nb_qps) {
|
||||
PMD_DRV_LOG(ERR, "vsi_queue_config_info argument wrong\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
qpair = qconfig->qpair;
|
||||
for (i = 0; i < qconfig->num_queue_pairs; i++) {
|
||||
if (qpair[i].rxq.queue_id > vsi->nb_qps - 1 ||
|
||||
qpair[i].txq.queue_id > vsi->nb_qps - 1) {
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
/* Apply VF RX queue setting to HMC */
|
||||
if (i40e_pf_host_hmc_config_rxq(hw, vf, &qpair[i].rxq)
|
||||
!= I40E_SUCCESS) {
|
||||
PMD_DRV_LOG(ERR, "Configure RX queue HMC failed");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
/* Apply VF TX queue setting to HMC */
|
||||
if (i40e_pf_host_hmc_config_txq(hw, vf, &qpair[i].txq)
|
||||
!= I40E_SUCCESS) {
|
||||
PMD_DRV_LOG(ERR, "Configure TX queue HMC failed");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
}
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES,
|
||||
ret, NULL, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_config_irq_map(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg, uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_irq_map_info *irqmap =
|
||||
(struct i40e_virtchnl_irq_map_info *)msg;
|
||||
|
||||
if (msglen < sizeof(struct i40e_virtchnl_irq_map_info)) {
|
||||
PMD_DRV_LOG(ERR, "buffer too short\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
/* Assume VF only have 1 vector to bind all queues */
|
||||
if (irqmap->num_vectors != 1) {
|
||||
PMD_DRV_LOG(ERR, "DKDK host only support 1 vector\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
if (irqmap->vecmap[0].vector_id == 0) {
|
||||
PMD_DRV_LOG(ERR, "DPDK host don't support use IRQ0\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
/* This MSIX intr store the intr in VF range */
|
||||
vf->vsi->msix_intr = irqmap->vecmap[0].vector_id;
|
||||
|
||||
/* Don't care how the TX/RX queue mapping with this vector.
|
||||
* Link all VF RX queues together. Only did mapping work.
|
||||
* VF can disable/enable the intr by itself.
|
||||
*/
|
||||
i40e_vsi_queues_bind_intr(vf->vsi);
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP,
|
||||
ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_switch_queues(struct i40e_pf_vf *vf,
|
||||
struct i40e_virtchnl_queue_select *qsel,
|
||||
bool on)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
int i;
|
||||
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
|
||||
uint16_t baseq = vf->vsi->base_queue;
|
||||
|
||||
if (qsel->rx_queues + qsel->tx_queues == 0)
|
||||
return I40E_ERR_PARAM;
|
||||
|
||||
/* always enable RX first and disable last */
|
||||
/* Enable RX if it's enable */
|
||||
if (on) {
|
||||
for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++)
|
||||
if (qsel->rx_queues & (1 << i)) {
|
||||
ret = i40e_switch_rx_queue(hw, baseq + i, on);
|
||||
if (ret != I40E_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable/Disable TX */
|
||||
for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++)
|
||||
if (qsel->tx_queues & (1 << i)) {
|
||||
ret = i40e_switch_tx_queue(hw, baseq + i, on);
|
||||
if (ret != I40E_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* disable RX last if it's disable */
|
||||
if (!on) {
|
||||
/* disable RX */
|
||||
for (i = 0; i < I40E_MAX_QP_NUM_PER_VF; i++)
|
||||
if (qsel->rx_queues & (1 << i)) {
|
||||
ret = i40e_switch_rx_queue(hw, baseq + i, on);
|
||||
if (ret != I40E_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_enable_queues(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_queue_select *q_sel =
|
||||
(struct i40e_virtchnl_queue_select *)msg;
|
||||
|
||||
if (msglen != sizeof(*q_sel)) {
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
ret = i40e_pf_host_switch_queues(vf, q_sel, true);
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_ENABLE_QUEUES,
|
||||
ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_disable_queues(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_queue_select *q_sel =
|
||||
(struct i40e_virtchnl_queue_select *)msg;
|
||||
|
||||
if (msglen != sizeof(*q_sel)) {
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
ret = i40e_pf_host_switch_queues(vf, q_sel, false);
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_DISABLE_QUEUES,
|
||||
ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_ether_addr_list *addr_list =
|
||||
(struct i40e_virtchnl_ether_addr_list *)msg;
|
||||
int i;
|
||||
struct ether_addr *mac;
|
||||
|
||||
if (msglen <= sizeof(*addr_list)) {
|
||||
PMD_DRV_LOG(ERR, "add_ether_address argument too short\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
for (i = 0; i < addr_list->num_elements; i++) {
|
||||
mac = (struct ether_addr *)(addr_list->list[i].addr);
|
||||
if(!is_valid_assigned_ether_addr(mac) ||
|
||||
i40e_vsi_add_mac(vf->vsi, mac)) {
|
||||
ret = I40E_ERR_INVALID_MAC_ADDR;
|
||||
goto send_msg;
|
||||
}
|
||||
}
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
|
||||
ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_del_ether_address(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_ether_addr_list *addr_list =
|
||||
(struct i40e_virtchnl_ether_addr_list *)msg;
|
||||
int i;
|
||||
struct ether_addr *mac;
|
||||
|
||||
if (msglen <= sizeof(*addr_list)) {
|
||||
PMD_DRV_LOG(ERR, "delete_ether_address argument too short\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
for (i = 0; i < addr_list->num_elements; i++) {
|
||||
mac = (struct ether_addr *)(addr_list->list[i].addr);
|
||||
if(!is_valid_assigned_ether_addr(mac) ||
|
||||
i40e_vsi_delete_mac(vf->vsi, mac)) {
|
||||
ret = I40E_ERR_INVALID_MAC_ADDR;
|
||||
goto send_msg;
|
||||
}
|
||||
}
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
|
||||
ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_add_vlan(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg, uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_vlan_filter_list *vlan_filter_list =
|
||||
(struct i40e_virtchnl_vlan_filter_list *)msg;
|
||||
int i;
|
||||
uint16_t *vid;
|
||||
|
||||
if (msglen <= sizeof(*vlan_filter_list)) {
|
||||
PMD_DRV_LOG(ERR, "add_vlan argument too short\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
vid = vlan_filter_list->vlan_id;
|
||||
|
||||
for (i = 0; i < vlan_filter_list->num_elements; i++) {
|
||||
ret = i40e_vsi_add_vlan(vf->vsi, vid[i]);
|
||||
if(ret != I40E_SUCCESS)
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_ADD_VLAN,
|
||||
ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_del_vlan(struct i40e_pf_vf *vf,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_vlan_filter_list *vlan_filter_list =
|
||||
(struct i40e_virtchnl_vlan_filter_list *)msg;
|
||||
int i;
|
||||
uint16_t *vid;
|
||||
|
||||
if (msglen <= sizeof(*vlan_filter_list)) {
|
||||
PMD_DRV_LOG(ERR, "delete_vlan argument too short\n");
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
vid = vlan_filter_list->vlan_id;
|
||||
for (i = 0; i < vlan_filter_list->num_elements; i++) {
|
||||
ret = i40e_vsi_delete_vlan(vf->vsi, vid[i]);
|
||||
if(ret != I40E_SUCCESS)
|
||||
goto send_msg;
|
||||
}
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_DEL_VLAN,
|
||||
ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_config_promisc_mode(
|
||||
struct i40e_pf_vf *vf,
|
||||
uint8_t *msg,
|
||||
__rte_unused uint16_t msglen)
|
||||
{
|
||||
int ret = I40E_SUCCESS;
|
||||
struct i40e_virtchnl_promisc_info *promisc =
|
||||
(struct i40e_virtchnl_promisc_info *)msg;
|
||||
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
|
||||
bool unicast = FALSE, multicast = FALSE;
|
||||
|
||||
if (promisc->flags & I40E_FLAG_VF_UNICAST_PROMISC)
|
||||
unicast = TRUE;
|
||||
ret = i40e_aq_set_vsi_unicast_promiscuous(hw,
|
||||
vf->vsi->seid, unicast, NULL);
|
||||
if (ret != I40E_SUCCESS)
|
||||
goto send_msg;
|
||||
|
||||
if (promisc->flags & I40E_FLAG_VF_MULTICAST_PROMISC)
|
||||
multicast = TRUE;
|
||||
ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid,
|
||||
multicast, NULL);
|
||||
|
||||
send_msg:
|
||||
i40e_pf_host_send_msg_to_vf(vf,
|
||||
I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, ret, NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf)
|
||||
{
|
||||
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));
|
||||
|
||||
return I40E_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
i40e_pf_host_process_cmd_get_link_status(struct i40e_pf_vf *vf)
|
||||
{
|
||||
struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(vf->pf->main_vsi);
|
||||
|
||||
/* Update link status first to acquire latest link change */
|
||||
i40e_dev_link_update(dev, 1);
|
||||
i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_LINK_STAT,
|
||||
I40E_SUCCESS, (uint8_t *)&dev->data->dev_link,
|
||||
sizeof(struct rte_eth_link));
|
||||
}
|
||||
|
||||
void
|
||||
i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
|
||||
uint16_t abs_vf_id, uint32_t opcode,
|
||||
__rte_unused uint32_t retval,
|
||||
uint8_t *msg,
|
||||
uint16_t msglen)
|
||||
{
|
||||
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
|
||||
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
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;
|
||||
|
||||
if (!dev || vf_id > pf->vf_num - 1 || !pf->vfs) {
|
||||
PMD_DRV_LOG(ERR, "invalid argument\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vf = &pf->vfs[vf_id];
|
||||
if (!vf->vsi) {
|
||||
PMD_DRV_LOG(ERR, "NO VSI associated with VF found\n");
|
||||
i40e_pf_host_send_msg_to_vf(vf, opcode,
|
||||
I40E_ERR_NO_AVAILABLE_VSI, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
case I40E_VIRTCHNL_OP_VERSION :
|
||||
PMD_DRV_LOG(INFO, "OP_VERSION received\n");
|
||||
i40e_pf_host_process_cmd_version(vf);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_RESET_VF :
|
||||
PMD_DRV_LOG(INFO, "OP_RESET_VF received\n");
|
||||
i40e_pf_host_process_cmd_reset_vf(vf);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_GET_VF_RESOURCES:
|
||||
PMD_DRV_LOG(INFO, "OP_GET_VF_RESOURCES received\n");
|
||||
i40e_pf_host_process_cmd_get_vf_resource(vf);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES:
|
||||
PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES received\n");
|
||||
i40e_pf_host_process_cmd_config_vsi_queues(vf,
|
||||
msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP:
|
||||
PMD_DRV_LOG(INFO, "OP_CONFIG_IRQ_MAP received\n");
|
||||
i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
|
||||
PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received\n");
|
||||
i40e_pf_host_process_cmd_enable_queues(vf,
|
||||
msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
|
||||
PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received\n");
|
||||
i40e_pf_host_process_cmd_disable_queues(vf,
|
||||
msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS:
|
||||
PMD_DRV_LOG(INFO, "OP_ADD_ETHER_ADDRESS received\n");
|
||||
i40e_pf_host_process_cmd_add_ether_address(vf,
|
||||
msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS:
|
||||
PMD_DRV_LOG(INFO, "OP_DEL_ETHER_ADDRESS received\n");
|
||||
i40e_pf_host_process_cmd_del_ether_address(vf,
|
||||
msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_ADD_VLAN:
|
||||
PMD_DRV_LOG(INFO, "OP_ADD_VLAN received\n");
|
||||
i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_DEL_VLAN:
|
||||
PMD_DRV_LOG(INFO, "OP_DEL_VLAN received\n");
|
||||
i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
|
||||
PMD_DRV_LOG(INFO, "OP_CONFIG_PROMISCUOUS_MODE received\n");
|
||||
i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, msglen);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_GET_STATS:
|
||||
PMD_DRV_LOG(INFO, "OP_GET_STATS received\n");
|
||||
i40e_pf_host_process_cmd_get_stats(vf);
|
||||
break;
|
||||
case I40E_VIRTCHNL_OP_GET_LINK_STAT:
|
||||
PMD_DRV_LOG(INFO, "OP_GET_LINK_STAT received\n");
|
||||
i40e_pf_host_process_cmd_get_link_status(vf);
|
||||
break;
|
||||
/* Don't add command supported below, which will
|
||||
* return an error code.
|
||||
*/
|
||||
case I40E_VIRTCHNL_OP_FCOE:
|
||||
PMD_DRV_LOG(ERR, "OP_FCOE received, not supported\n");
|
||||
default:
|
||||
PMD_DRV_LOG(ERR, "%u received, not supported\n",
|
||||
opcode);
|
||||
i40e_pf_host_send_msg_to_vf(vf, opcode,
|
||||
I40E_ERR_PARAM, NULL, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
i40e_pf_host_init(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
|
||||
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
|
||||
int ret, i;
|
||||
uint32_t val;
|
||||
|
||||
PMD_INIT_FUNC_TRACE();
|
||||
|
||||
/**
|
||||
* return if SRIOV not enabled, VF number not configured or
|
||||
* no queue assigned.
|
||||
*/
|
||||
if(!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 || pf->vf_nb_qps == 0)
|
||||
return I40E_SUCCESS;
|
||||
|
||||
/* Allocate memory to store VF structure */
|
||||
pf->vfs = rte_zmalloc("i40e_pf_vf",sizeof(*pf->vfs) * pf->vf_num, 0);
|
||||
if(pf->vfs == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Disable irq0 for VFR event */
|
||||
i40e_pf_disable_irq0(hw);
|
||||
|
||||
/* Disable VF link status interrupt */
|
||||
val = I40E_READ_REG(hw, I40E_PFGEN_PORTMDIO_NUM);
|
||||
val &= ~I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK;
|
||||
I40E_WRITE_REG(hw, I40E_PFGEN_PORTMDIO_NUM, val);
|
||||
I40E_WRITE_FLUSH(hw);
|
||||
|
||||
for (i = 0; i < pf->vf_num; i++) {
|
||||
pf->vfs[i].pf = pf;
|
||||
pf->vfs[i].state = I40E_VF_INACTIVE;
|
||||
pf->vfs[i].vf_idx = i;
|
||||
ret = i40e_pf_host_vf_reset(&pf->vfs[i], 0);
|
||||
if (ret != I40E_SUCCESS)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* restore irq0 */
|
||||
i40e_pf_enable_irq0(hw);
|
||||
|
||||
return I40E_SUCCESS;
|
||||
|
||||
fail:
|
||||
rte_free(pf->vfs);
|
||||
i40e_pf_enable_irq0(hw);
|
||||
|
||||
return ret;
|
||||
}
|
67
lib/librte_pmd_i40e/i40e_pf.h
Normal file
67
lib/librte_pmd_i40e/i40e_pf.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _I40E_PF_H_
|
||||
#define _I40E_PF_H_
|
||||
|
||||
/* VERSION info to exchange between VF and PF host. In case VF works with
|
||||
* ND kernel driver, it reads I40E_VIRTCHNL_VERSION_MAJOR/MINOR. In
|
||||
* case works with DPDK host, it reads version below. Then VF realize who it
|
||||
* is talking to and use proper language to communicate.
|
||||
* */
|
||||
#define I40E_DPDK_SIGNATURE ('D' << 24 | 'P' << 16 | 'D' << 8 | 'K')
|
||||
#define I40E_DPDK_VERSION_MAJOR I40E_DPDK_SIGNATURE
|
||||
#define I40E_DPDK_VERSION_MINOR 0
|
||||
|
||||
/* Default setting on number of VSIs that VF can contain */
|
||||
#define I40E_DEFAULT_VF_VSI_NUM 1
|
||||
|
||||
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 {
|
||||
/* Keep some gap between Linu PF commands and DPDK PF specific commands */
|
||||
I40E_VIRTCHNL_OP_GET_LINK_STAT = I40E_VIRTCHNL_OP_EVENT + 0x100,
|
||||
};
|
||||
|
||||
int i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset);
|
||||
void i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
|
||||
uint16_t abs_vf_id, uint32_t opcode,
|
||||
__rte_unused uint32_t retval,
|
||||
uint8_t *msg, uint16_t msglen);
|
||||
int i40e_pf_host_init(struct rte_eth_dev *dev);
|
||||
|
||||
#endif /* _I40E_PF_H_ */
|
2204
lib/librte_pmd_i40e/i40e_rxtx.c
Normal file
2204
lib/librte_pmd_i40e/i40e_rxtx.c
Normal file
File diff suppressed because it is too large
Load Diff
189
lib/librte_pmd_i40e/i40e_rxtx.h
Normal file
189
lib/librte_pmd_i40e/i40e_rxtx.h
Normal file
@ -0,0 +1,189 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _I40E_RXTX_H_
|
||||
#define _I40E_RXTX_H_
|
||||
|
||||
/**
|
||||
* 32 bits tx flags, high 16 bits for L2TAG1 (VLAN),
|
||||
* low 16 bits for others.
|
||||
*/
|
||||
#define I40E_TX_FLAG_L2TAG1_SHIFT 16
|
||||
#define I40E_TX_FLAG_L2TAG1_MASK 0xffff0000
|
||||
#define I40E_TX_FLAG_CSUM ((uint32_t)(1 << 0))
|
||||
#define I40E_TX_FLAG_INSERT_VLAN ((uint32_t)(1 << 1))
|
||||
#define I40E_TX_FLAG_TSYN ((uint32_t)(1 << 2))
|
||||
|
||||
#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
|
||||
#define RTE_PMD_I40E_RX_MAX_BURST 32
|
||||
#endif
|
||||
|
||||
#define I40E_RXBUF_SZ_1024 1024
|
||||
#define I40E_RXBUF_SZ_2048 2048
|
||||
|
||||
enum i40e_header_split_mode {
|
||||
i40e_header_split_none = 0,
|
||||
i40e_header_split_enabled = 1,
|
||||
i40e_header_split_always = 2,
|
||||
i40e_header_split_reserved
|
||||
};
|
||||
|
||||
#define I40E_HEADER_SPLIT_NONE ((uint8_t)0)
|
||||
#define I40E_HEADER_SPLIT_L2 ((uint8_t)(1 << 0))
|
||||
#define I40E_HEADER_SPLIT_IP ((uint8_t)(1 << 1))
|
||||
#define I40E_HEADER_SPLIT_UDP_TCP ((uint8_t)(1 << 2))
|
||||
#define I40E_HEADER_SPLIT_SCTP ((uint8_t)(1 << 3))
|
||||
#define I40E_HEADER_SPLIT_ALL (I40E_HEADER_SPLIT_L2 | \
|
||||
I40E_HEADER_SPLIT_IP | \
|
||||
I40E_HEADER_SPLIT_UDP_TCP | \
|
||||
I40E_HEADER_SPLIT_SCTP)
|
||||
|
||||
/* HW desc structure, both 16-byte and 32-byte types are supported */
|
||||
#ifdef RTE_LIBRTE_I40E_16BYTE_RX_DESC
|
||||
#define i40e_rx_desc i40e_16byte_rx_desc
|
||||
#else
|
||||
#define i40e_rx_desc i40e_32byte_rx_desc
|
||||
#endif
|
||||
|
||||
struct i40e_rx_entry {
|
||||
struct rte_mbuf *mbuf;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure associated with each RX queue.
|
||||
*/
|
||||
struct i40e_rx_queue {
|
||||
struct rte_mempool *mp; /**< mbuf pool to populate RX ring */
|
||||
volatile union i40e_rx_desc *rx_ring;/**< RX ring virtual address */
|
||||
uint64_t rx_ring_phys_addr; /**< RX ring DMA address */
|
||||
struct i40e_rx_entry *sw_ring; /**< address of RX soft ring */
|
||||
uint16_t nb_rx_desc; /**< number of RX descriptors */
|
||||
uint16_t rx_free_thresh; /**< max free RX desc to hold */
|
||||
uint16_t rx_tail; /**< current value of tail */
|
||||
uint16_t nb_rx_hold; /**< number of held free RX desc */
|
||||
struct rte_mbuf *pkt_first_seg; /**< first segment of current packet */
|
||||
struct rte_mbuf *pkt_last_seg; /**< last segment of current packet */
|
||||
#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
|
||||
uint16_t rx_nb_avail; /**< number of staged packets ready */
|
||||
uint16_t rx_next_avail; /**< index of next staged packets */
|
||||
uint16_t rx_free_trigger; /**< triggers rx buffer allocation */
|
||||
struct rte_mbuf fake_mbuf; /**< dummy mbuf */
|
||||
struct rte_mbuf *rx_stage[RTE_PMD_I40E_RX_MAX_BURST * 2];
|
||||
#endif
|
||||
uint8_t port_id; /**< device port ID */
|
||||
uint8_t crc_len; /**< 0 if CRC stripped, 4 otherwise */
|
||||
uint16_t queue_id; /**< RX queue index */
|
||||
uint16_t reg_idx; /**< RX queue register index */
|
||||
uint8_t drop_en; /**< if not 0, set register bit */
|
||||
volatile uint8_t *qrx_tail; /**< register address of tail */
|
||||
struct i40e_vsi *vsi; /**< the VSI this queue belongs to */
|
||||
uint16_t rx_buf_len; /* The packet buffer size */
|
||||
uint16_t rx_hdr_len; /* The header buffer size */
|
||||
uint16_t max_pkt_len; /* Maximum packet length */
|
||||
uint8_t hs_mode; /* Header Split mode */
|
||||
bool q_set; /**< indicate if rx queue has been configured */
|
||||
};
|
||||
|
||||
struct i40e_tx_entry {
|
||||
struct rte_mbuf *mbuf;
|
||||
uint16_t next_id;
|
||||
uint16_t last_id;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure associated with each TX queue.
|
||||
*/
|
||||
struct i40e_tx_queue {
|
||||
uint16_t nb_tx_desc; /**< number of TX descriptors */
|
||||
uint64_t tx_ring_phys_addr; /**< TX ring DMA address */
|
||||
volatile struct i40e_tx_desc *tx_ring; /**< TX ring virtual address */
|
||||
struct i40e_tx_entry *sw_ring; /**< virtual address of SW ring */
|
||||
uint16_t tx_tail; /**< current value of tail register */
|
||||
volatile uint8_t *qtx_tail; /**< register address of tail */
|
||||
uint16_t nb_tx_used; /**< number of TX desc used since RS bit set */
|
||||
/**< index to last TX descriptor to have been cleaned */
|
||||
uint16_t last_desc_cleaned;
|
||||
/**< Total number of TX descriptors ready to be allocated. */
|
||||
uint16_t nb_tx_free;
|
||||
/**< Number of TX descriptors to use before RS bit is set. */
|
||||
uint16_t tx_free_thresh; /**< minimum TX before freeing. */
|
||||
/** Number of TX descriptors to use before RS bit is set. */
|
||||
uint16_t tx_rs_thresh;
|
||||
uint8_t pthresh; /**< Prefetch threshold register. */
|
||||
uint8_t hthresh; /**< Host threshold register. */
|
||||
uint8_t wthresh; /**< Write-back threshold reg. */
|
||||
uint8_t port_id; /**< Device port identifier. */
|
||||
uint16_t queue_id; /**< TX queue index. */
|
||||
uint16_t reg_idx;
|
||||
uint32_t txq_flags;
|
||||
struct i40e_vsi *vsi; /**< the VSI this queue belongs to */
|
||||
uint16_t tx_next_dd;
|
||||
uint16_t tx_next_rs;
|
||||
bool q_set; /**< indicate if tx queue has been configured */
|
||||
};
|
||||
|
||||
int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
|
||||
uint16_t queue_idx,
|
||||
uint16_t nb_desc,
|
||||
unsigned int socket_id,
|
||||
const struct rte_eth_rxconf *rx_conf,
|
||||
struct rte_mempool *mp);
|
||||
int i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
|
||||
uint16_t queue_idx,
|
||||
uint16_t nb_desc,
|
||||
unsigned int socket_id,
|
||||
const struct rte_eth_txconf *tx_conf);
|
||||
void i40e_dev_rx_queue_release(void *rxq);
|
||||
void i40e_dev_tx_queue_release(void *txq);
|
||||
uint16_t i40e_recv_pkts(void *rx_queue,
|
||||
struct rte_mbuf **rx_pkts,
|
||||
uint16_t nb_pkts);
|
||||
uint16_t i40e_recv_scattered_pkts(void *rx_queue,
|
||||
struct rte_mbuf **rx_pkts,
|
||||
uint16_t nb_pkts);
|
||||
uint16_t i40e_xmit_pkts(void *tx_queue,
|
||||
struct rte_mbuf **tx_pkts,
|
||||
uint16_t nb_pkts);
|
||||
int i40e_tx_queue_init(struct i40e_tx_queue *txq);
|
||||
int i40e_rx_queue_init(struct i40e_rx_queue *rxq);
|
||||
void i40e_free_tx_resources(struct i40e_tx_queue *txq);
|
||||
void i40e_free_rx_resources(struct i40e_rx_queue *rxq);
|
||||
void i40e_dev_clear_queues(struct rte_eth_dev *dev);
|
||||
int i40e_alloc_rx_queue_mbufs(struct i40e_rx_queue *rxq);
|
||||
void i40e_rx_queue_release_mbufs(struct i40e_rx_queue *rxq);
|
||||
|
||||
uint32_t i40e_dev_rx_queue_count(struct rte_eth_dev *dev,
|
||||
uint16_t rx_queue_id);
|
||||
int i40e_dev_rx_descriptor_done(void *rx_queue, uint16_t offset);
|
||||
|
||||
#endif /* _I40E_RXTX_H_ */
|
@ -185,6 +185,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_VIRTIO_PMD),y)
|
||||
LDLIBS += -lrte_pmd_virtio_uio
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RTE_LIBRTE_I40E_PMD),y)
|
||||
LDLIBS += -lrte_pmd_i40e
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
|
||||
LDLIBS += -lrte_pmd_ixgbe
|
||||
endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user