qede: add core driver

The Qlogic Everest Driver for Ethernet(QEDE) Poll Mode Driver(PMD) is
the DPDK specific module for QLogic FastLinQ QL4xxxx 25G/40G CNA family
of adapters as well as their virtual functions (VF) in SR-IOV context.

This patch adds QEDE PMD, which interacts with base driver and
initialises the HW.

This patch content also includes:
 - eth_dev_ops callbacks
 - Rx/Tx support for the driver
 - link default configuration
 - change link property
 - link up/down/update notifications
 - vlan offload and filtering capability
 - device/function/port statistics
 - qede nic guide and updated overview.rst

Note that the follow on commits contain the code for the features mentioned
in documents but not implemented in this patch.

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
This commit is contained in:
Rasesh Mody 2016-04-27 07:18:37 -07:00 committed by Bruce Richardson
parent ec94dbc573
commit 2ea6f76aff
14 changed files with 3899 additions and 42 deletions

View File

@ -337,6 +337,7 @@ M: Harish Patil <harish.patil@qlogic.com>
M: Rasesh Mody <rasesh.mody@qlogic.com>
M: Sony Chacko <sony.chacko@qlogic.com>
F: drivers/net/qede/
F: doc/guides/nics/qede.rst
RedHat virtio
M: Huawei Xie <huawei.xie@intel.com>

View File

@ -48,6 +48,7 @@ Network Interface Controller Drivers
mlx4
mlx5
nfp
qede
szedata2
virtio
vhost

View File

@ -74,40 +74,40 @@ Most of these differences are summarized below.
.. table:: Features availability in networking drivers
==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Feature a b b b c e e e i i i i i i i i i i f f f f m m m n n p r s v v v v x
f n n o x 1 n n 4 4 4 4 g g x x x x m m m m l l p f u c i z h i i m e
p x x n g 0 a i 0 0 0 0 b b g g g g 1 1 1 1 x x i p l a n e o r r x n
a 2 2 d b 0 c e e e e v b b b b 0 0 0 0 4 5 p l p g d s t t n v
c x x i e 0 . v v f e e e e k k k k e a t i i e i
k v n . f f . v v . v v t o o t r
e f g . . . f f . f f a . 3 t
t v v v v v v 2 v
e e e e e e e
c c c c c c c
==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Feature a b b b c e e e i i i i i i i i i i f f f f m m m n n p q q r s v v v v x
f n n o x 1 n n 4 4 4 4 g g x x x x m m m m l l p f u c e e i z h i i m e
p x x n g 0 a i 0 0 0 0 b b g g g g 1 1 1 1 x x i p l a d d n e o r r x n
a 2 2 d b 0 c e e e e v b b b b 0 0 0 0 4 5 p l p e e g d s t t n v
c x x i e 0 . v v f e e e e k k k k e v a t i i e i
k v n . f f . v v . v v f t o o t r
e f g . . . f f . f f a . 3 t
t v v v v v v 2 v
e e e e e e e
c c c c c c c
==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Speed capabilities
Link status Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Link status event Y Y Y Y Y Y Y Y Y Y Y
Queue status event Y
Link status Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Link status event Y Y Y Y Y Y Y Y Y Y Y Y Y
Queue status event Y
Rx interrupt Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Queue start/stop Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Queue start/stop Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
MTU update Y Y Y Y Y Y Y Y Y Y
Jumbo frame Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Scattered Rx Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Jumbo frame Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Scattered Rx Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
LRO Y Y Y Y
TSO Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Promiscuous mode Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Allmulticast mode Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Unicast MAC filter Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Multicast MAC filter Y Y Y Y Y Y Y Y Y Y Y Y Y
RSS hash Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Promiscuous mode Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Allmulticast mode Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Unicast MAC filter Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Multicast MAC filter Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
RSS hash Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
RSS key update Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
RSS reta update Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VMDq Y Y Y Y Y Y Y
SR-IOV Y Y Y Y Y Y Y Y Y
SR-IOV Y Y Y Y Y Y Y Y Y Y
DCB Y Y Y Y Y
VLAN filter Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VLAN filter Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Ethertype filter Y Y Y Y Y
N-tuple filter Y Y Y
SYN filter Y Y Y
@ -115,38 +115,38 @@ Most of these differences are summarized below.
Flexible filter Y
Hash filter Y Y Y Y
Flow director Y Y Y Y Y
Flow control Y Y Y Y Y Y Y
Flow control Y Y Y Y Y Y Y Y Y
Rate limitation Y Y
Traffic mirroring Y Y Y Y
CRC offload Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VLAN offload Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
CRC offload Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VLAN offload Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
QinQ offload Y Y Y Y Y Y Y
L3 checksum offload Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
L4 checksum offload Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Inner L3 checksum Y Y Y Y Y Y
Inner L4 checksum Y Y Y Y Y Y
Packet type parsing Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Packet type parsing Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Timesync Y Y Y Y Y
Basic stats Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Basic stats Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Extended stats Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Stats per queue Y Y Y Y Y Y Y Y Y Y Y Y
Stats per queue Y Y Y Y Y Y Y Y Y Y Y Y Y Y
EEPROM dump Y Y Y
Registers dump Y Y Y Y Y Y
Multiprocess aware Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
BSD nic_uio Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Linux UIO Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Linux VFIO Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Other kdrv Y Y Y
ARMv7 Y Y Y
ARMv8 Y Y Y
Multiprocess aware Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
BSD nic_uio Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Linux UIO Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Linux VFIO Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Other kdrv Y Y Y
ARMv7 Y Y Y
ARMv8 Y Y Y
Power8 Y Y Y
TILE-Gx Y
x86-32 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
x86-64 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Usage doc Y Y Y Y Y Y Y Y Y
x86-32 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
x86-64 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
Usage doc Y Y Y Y Y Y Y Y Y Y Y
Design doc
Perf doc
==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
.. Note::

315
doc/guides/nics/qede.rst Normal file
View File

@ -0,0 +1,315 @@
.. BSD LICENSE
Copyright (c) 2016 QLogic Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of QLogic 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.
QEDE Poll Mode Driver
======================
The QEDE poll mode driver library (**librte_pmd_qede**) implements support
for **QLogic FastLinQ QL4xxxx 25G/40G CNA** family of adapters as well
as their virtual functions (VF) in SR-IOV context. It is supported on
several standard Linux distros like RHEL7.x, SLES12.x and Ubuntu.
It is compile-tested under FreeBSD OS.
More information can be found at `QLogic Corporation's Website
<http://www.qlogic.com>`_.
Supported Features
------------------
- Unicast/Multicast filtering
- Promiscuous mode
- Allmulti mode
- Port hardware statistics
- Jumbo frames (using single buffer)
- VLAN offload - Filtering and stripping
- Stateless checksum offloads (IPv4/TCP/UDP)
- Multiple Rx/Tx queues (queue-pairs)
- RSS (with default table/key)
- TSS
- Multiple MAC address
- Default pause flow control
- SR-IOV VF
Non-supported Features
----------------------
- Scatter-Gather Rx/Tx frames
- User configurable RETA table/key
- Unequal number of Rx/Tx queues
- MTU change (dynamic)
- SR-IOV PF
- Tunneling offloads
- Reload of the PMD after a non-graceful termination
Supported QLogic Adapters
-------------------------
- QLogic FastLinQ QL4xxxx 25G/40G CNAs
Prerequisites
-------------
- Requires firmware version **8.7.x.** and management
firmware version **8.7.x or higher**. Firmware may be available
inbox in certain newer Linux distros under the standard directory
``E.g. /lib/firmware/qed/qed_init_values_zipped-8.7.7.0.bin``
- If the required firmware files are not available then visit
`QLogic Driver Download Center <http://driverdownloads.qlogic.com>`_.
- This driver relies on external zlib library (-lz) for uncompressing
the firmware file.
Performance note
~~~~~~~~~~~~~~~~
- For better performance, it is recommended to use 4K or higher RX/TX rings.
Config File Options
~~~~~~~~~~~~~~~~~~~
The following options can be modified in the ``.config`` file. Please note that
enabling debugging options may affect system performance.
- ``CONFIG_RTE_LIBRTE_QEDE_PMD`` (default **y**)
Toggle compilation of QEDE PMD driver.
- ``CONFIG_RTE_LIBRTE_QEDE_DEBUG_INFO`` (default **n**)
Toggle display of generic debugging messages.
- ``CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRV`` (default **n**)
Toggle display of ecore related messages.
- ``CONFIG_RTE_LIBRTE_QEDE_DEBUG_TX`` (default **n**)
Toggle display of transmit fast path run-time messages.
- ``CONFIG_RTE_LIBRTE_QEDE_DEBUG_RX`` (default **n**)
Toggle display of receive fast path run-time messages.
- ``CONFIG_RTE_LIBRTE_QEDE_FW`` (default **""**)
Gives absolute path of firmware file.
``Eg: "/lib/firmware/qed/qed_init_values_zipped-8.7.7.0.bin"``
Empty string indicates driver will pick up the firmware file
from the default location.
Driver Compilation
~~~~~~~~~~~~~~~~~~
To compile QEDE PMD for Linux x86_64 gcc target, run the following ``make``
command::
cd <DPDK-source-directory>
make config T=x86_64-native-linuxapp-gcc install
To compile QEDE PMD for Linux x86_64 clang target, run the following ``make``
command::
cd <DPDK-source-directory>
make config T=x86_64-native-linuxapp-clang install
To compile QEDE PMD for FreeBSD x86_64 clang target, run the following ``gmake``
command::
cd <DPDK-source-directory>
gmake config T=x86_64-native-bsdapp-clang install
To compile QEDE PMD for FreeBSD x86_64 gcc target, run the following ``gmake``
command::
cd <DPDK-source-directory>
gmake config T=x86_64-native-bsdapp-gcc install -Wl,-rpath=\
/usr/local/lib/gcc48 CC=gcc48
Sample Application Notes
~~~~~~~~~~~~~~~~~~~~~~~~
This section demonstrates how to launch ``testpmd`` with QLogic 4xxxx
devices managed by ``librte_pmd_qede`` in Linux operating system.
#. Request huge pages:
.. code-block:: console
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages/ \
nr_hugepages
#. Load ``igb_uio`` driver:
.. code-block:: console
insmod ./x86_64-native-linuxapp-gcc/kmod/igb_uio.ko
#. Bind the QLogic 4xxxx adapters to ``igb_uio`` loaded in the
previous step:
.. code-block:: console
./tools/dpdk_nic_bind.py --bind igb_uio 0000:84:00.0 0000:84:00.1 \
0000:84:00.2 0000:84:00.3
#. Start ``testpmd`` with basic parameters:
(Enable QEDE_DEBUG_INFO=y to view informational messages)
.. code-block:: console
testpmd -c 0xff1 -n 4 -- -i --nb-cores=8 --portmask=0xf --rxd=4096 \
--txd=4096 --txfreet=4068 --enable-rx-cksum --rxq=4 --txq=4 \
--rss-ip --rss-udp
[...]
EAL: PCI device 0000:84:00.0 on NUMA socket 1
EAL: probe driver: 1077:1634 rte_qede_pmd
EAL: Not managed by a supported kernel driver, skipped
EAL: PCI device 0000:84:00.1 on NUMA socket 1
EAL: probe driver: 1077:1634 rte_qede_pmd
EAL: Not managed by a supported kernel driver, skipped
EAL: PCI device 0000:88:00.0 on NUMA socket 1
EAL: probe driver: 1077:1656 rte_qede_pmd
EAL: PCI memory mapped at 0x7f738b200000
EAL: PCI memory mapped at 0x7f738b280000
EAL: PCI memory mapped at 0x7f738b300000
PMD: Chip details : BB1
PMD: Driver version : QEDE PMD 8.7.9.0_1.0.0
PMD: Firmware version : 8.7.7.0
PMD: Management firmware version : 8.7.8.0
PMD: Firmware file : /lib/firmware/qed/qed_init_values_zipped-8.7.7.0.bin
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_common_dev_init:macaddr \
00:0e:1e:d2:09:9c
[...]
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_tx_queue_setup:txq 0 num_desc 4096 \
tx_free_thresh 4068 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_tx_queue_setup:txq 1 num_desc 4096 \
tx_free_thresh 4068 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_tx_queue_setup:txq 2 num_desc 4096 \
tx_free_thresh 4068 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_tx_queue_setup:txq 3 num_desc 4096 \
tx_free_thresh 4068 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_rx_queue_setup:rxq 0 num_desc 4096 \
rx_buf_size=2148 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_rx_queue_setup:rxq 1 num_desc 4096 \
rx_buf_size=2148 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_rx_queue_setup:rxq 2 num_desc 4096 \
rx_buf_size=2148 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_rx_queue_setup:rxq 3 num_desc 4096 \
rx_buf_size=2148 socket 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_dev_start:port 0
[QEDE PMD: (84:00.0:dpdk-port-0)]qede_dev_start:link status: down
[...]
Checking link statuses...
Port 0 Link Up - speed 25000 Mbps - full-duplex
Port 1 Link Up - speed 25000 Mbps - full-duplex
Port 2 Link Up - speed 25000 Mbps - full-duplex
Port 3 Link Up - speed 25000 Mbps - full-duplex
Done
testpmd>
SR-IOV: Prerequisites and Sample Application Notes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This section provides instructions to configure SR-IOV with Linux OS.
**Note**: librte_pmd_qede will be used to bind to SR-IOV VF device and Linux native kernel driver (QEDE) will function as SR-IOV PF driver.
#. Verify SR-IOV and ARI capability is enabled on the adapter using ``lspci``:
.. code-block:: console
lspci -s <slot> -vvv
Example output:
.. code-block:: console
[...]
Capabilities: [1b8 v1] Alternative Routing-ID Interpretation (ARI)
[...]
Capabilities: [1c0 v1] Single Root I/O Virtualization (SR-IOV)
[...]
Kernel driver in use: igb_uio
#. Load the kernel module:
.. code-block:: console
modprobe qede
Example output:
.. code-block:: console
systemd-udevd[4848]: renamed network interface eth0 to ens5f0
systemd-udevd[4848]: renamed network interface eth1 to ens5f1
#. Bring up the PF ports:
.. code-block:: console
ifconfig ens5f0 up
ifconfig ens5f1 up
#. Create VF device(s):
Echo the number of VFs to be created into ``"sriov_numvfs"`` sysfs entry
of the parent PF.
Example output:
.. code-block:: console
echo 2 > /sys/devices/pci0000:00/0000:00:03.0/0000:81:00.0/sriov_numvfs
#. Assign VF MAC address:
Assign MAC address to the VF using iproute2 utility. The syntax is::
ip link set <PF iface> vf <VF id> mac <macaddr>
Example output:
.. code-block:: console
ip link set ens5f0 vf 0 mac 52:54:00:2f:9d:e8
#. PCI Passthrough:
The VF devices may be passed through to the guest VM using ``virt-manager`` or
``virsh``. QEDE PMD should be used to bind the VF devices in the guest VM
using the instructions outlined in the Application notes above.

View File

@ -6,9 +6,18 @@
include $(RTE_SDK)/mk/rte.vars.mk
#
# library name
#
LIB = librte_pmd_qede.a
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
EXPORT_MAP := rte_pmd_qede_version.map
LIBABIVER := 1
#
# OS
#
@ -72,6 +81,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_init_ops.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_mcp.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/ecore_int.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += base/bcm_osal.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_main.c
SRCS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede_rxtx.c
# dependent libs:
DEPDIRS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += lib/librte_eal lib/librte_ether

View File

@ -0,0 +1,176 @@
/*
* Copyright (c) 2016 QLogic Corporation.
* All rights reserved.
* www.qlogic.com
*
* See LICENSE.qede_pmd for copyright and licensing details.
*/
#ifndef _QEDE_ETH_IF_H
#define _QEDE_ETH_IF_H
#include "qede_if.h"
/*forward decl */
struct eth_slow_path_rx_cqe;
#define INIT_STRUCT_FIELD(field, value) .field = value
#define QED_ETH_INTERFACE_VERSION 609
#define QEDE_MAX_MCAST_FILTERS 64
enum qed_filter_rx_mode_type {
QED_FILTER_RX_MODE_TYPE_REGULAR,
QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC,
QED_FILTER_RX_MODE_TYPE_PROMISC,
};
enum qed_filter_xcast_params_type {
QED_FILTER_XCAST_TYPE_ADD,
QED_FILTER_XCAST_TYPE_DEL,
QED_FILTER_XCAST_TYPE_REPLACE,
};
enum qed_filter_type {
QED_FILTER_TYPE_UCAST,
QED_FILTER_TYPE_MCAST,
QED_FILTER_TYPE_RX_MODE,
QED_MAX_FILTER_TYPES,
};
struct qed_dev_eth_info {
struct qed_dev_info common;
uint8_t num_queues;
uint8_t num_tc;
struct ether_addr port_mac;
uint8_t num_vlan_filters;
uint32_t num_mac_addrs;
};
struct qed_update_vport_rss_params {
uint16_t rss_ind_table[128];
uint32_t rss_key[10];
};
struct qed_stop_rxq_params {
uint8_t rss_id;
uint8_t rx_queue_id;
uint8_t vport_id;
bool eq_completion_only;
};
struct qed_update_vport_params {
uint8_t vport_id;
uint8_t update_vport_active_flg;
uint8_t vport_active_flg;
uint8_t update_inner_vlan_removal_flg;
uint8_t inner_vlan_removal_flg;
uint8_t update_tx_switching_flg;
uint8_t tx_switching_flg;
uint8_t update_accept_any_vlan_flg;
uint8_t accept_any_vlan;
uint8_t update_rss_flg;
struct qed_update_vport_rss_params rss_params;
};
struct qed_start_vport_params {
bool remove_inner_vlan;
bool handle_ptp_pkts;
bool gro_enable;
bool drop_ttl0;
uint8_t vport_id;
uint16_t mtu;
bool clear_stats;
};
struct qed_stop_txq_params {
uint8_t rss_id;
uint8_t tx_queue_id;
};
struct qed_filter_ucast_params {
enum qed_filter_xcast_params_type type;
uint8_t vlan_valid;
uint16_t vlan;
uint8_t mac_valid;
unsigned char mac[ETHER_ADDR_LEN];
};
struct qed_filter_mcast_params {
enum qed_filter_xcast_params_type type;
uint8_t num;
unsigned char mac[QEDE_MAX_MCAST_FILTERS][ETHER_ADDR_LEN];
};
union qed_filter_type_params {
enum qed_filter_rx_mode_type accept_flags;
struct qed_filter_ucast_params ucast;
struct qed_filter_mcast_params mcast;
};
struct qed_filter_params {
enum qed_filter_type type;
union qed_filter_type_params filter;
};
struct qed_eth_ops {
const struct qed_common_ops *common;
int (*fill_dev_info)(struct ecore_dev *edev,
struct qed_dev_eth_info *info);
int (*vport_start)(struct ecore_dev *edev,
struct qed_start_vport_params *params);
int (*vport_stop)(struct ecore_dev *edev, uint8_t vport_id);
int (*vport_update)(struct ecore_dev *edev,
struct qed_update_vport_params *params);
int (*q_rx_start)(struct ecore_dev *cdev,
uint8_t rss_id, uint8_t rx_queue_id,
uint8_t vport_id, uint16_t sb,
uint8_t sb_index, uint16_t bd_max_bytes,
dma_addr_t bd_chain_phys_addr,
dma_addr_t cqe_pbl_addr,
uint16_t cqe_pbl_size, void OSAL_IOMEM * *pp_prod);
int (*q_rx_stop)(struct ecore_dev *edev,
struct qed_stop_rxq_params *params);
int (*q_tx_start)(struct ecore_dev *edev,
uint8_t rss_id, uint16_t tx_queue_id,
uint8_t vport_id, uint16_t sb,
uint8_t sb_index,
dma_addr_t pbl_addr,
uint16_t pbl_size, void OSAL_IOMEM * *pp_doorbell);
int (*q_tx_stop)(struct ecore_dev *edev,
struct qed_stop_txq_params *params);
int (*eth_cqe_completion)(struct ecore_dev *edev,
uint8_t rss_id,
struct eth_slow_path_rx_cqe *cqe);
int (*fastpath_stop)(struct ecore_dev *edev);
void (*get_vport_stats)(struct ecore_dev *edev,
struct ecore_eth_stats *stats);
int (*filter_config)(struct ecore_dev *edev,
struct qed_filter_params *params);
};
/* externs */
extern const struct qed_common_ops qed_common_ops_pass;
void qed_put_eth_ops(void);
int qed_configure_filter_rx_mode(struct ecore_dev *edev,
enum qed_filter_rx_mode_type type);
#endif /* _QEDE_ETH_IF_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2016 QLogic Corporation.
* All rights reserved.
* www.qlogic.com
*
* See LICENSE.qede_pmd for copyright and licensing details.
*/
#ifndef _QEDE_ETHDEV_H_
#define _QEDE_ETHDEV_H_
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_dev.h>
/* ecore includes */
#include "base/bcm_osal.h"
#include "base/ecore.h"
#include "base/ecore_dev_api.h"
#include "base/ecore_sp_api.h"
#include "base/ecore_mcp_api.h"
#include "base/ecore_hsi_common.h"
#include "base/ecore_int_api.h"
#include "base/ecore_chain.h"
#include "base/ecore_status.h"
#include "base/ecore_hsi_eth.h"
#include "base/ecore_dev_api.h"
#include "qede_logs.h"
#include "qede_if.h"
#include "qede_eth_if.h"
#include "qede_rxtx.h"
#define qede_stringify1(x...) #x
#define qede_stringify(x...) qede_stringify1(x)
/* Driver versions */
#define QEDE_PMD_VER_PREFIX "QEDE PMD"
#define QEDE_PMD_VERSION_MAJOR 1
#define QEDE_PMD_VERSION_MINOR 0
#define QEDE_PMD_VERSION_REVISION 6
#define QEDE_PMD_VERSION_PATCH 1
#define QEDE_MAJOR_VERSION 8
#define QEDE_MINOR_VERSION 7
#define QEDE_REVISION_VERSION 9
#define QEDE_ENGINEERING_VERSION 0
#define QEDE_DRV_MODULE_VERSION qede_stringify(QEDE_MAJOR_VERSION) "." \
qede_stringify(QEDE_MINOR_VERSION) "." \
qede_stringify(QEDE_REVISION_VERSION) "." \
qede_stringify(QEDE_ENGINEERING_VERSION)
#define QEDE_RSS_INDIR_INITED (1 << 0)
#define QEDE_RSS_KEY_INITED (1 << 1)
#define QEDE_RSS_CAPS_INITED (1 << 2)
#define QEDE_MAX_RSS_CNT(edev) ((edev)->dev_info.num_queues)
#define QEDE_MAX_TSS_CNT(edev) ((edev)->dev_info.num_queues * \
(edev)->dev_info.num_tc)
#define QEDE_RSS_CNT(edev) ((edev)->num_rss)
#define QEDE_TSS_CNT(edev) ((edev)->num_rss * (edev)->num_tc)
#define QEDE_DUPLEX_FULL 1
#define QEDE_DUPLEX_HALF 2
#define QEDE_DUPLEX_UNKNOWN 0xff
#define QEDE_SUPPORTED_AUTONEG (1 << 6)
#define QEDE_SUPPORTED_PAUSE (1 << 13)
#define QEDE_INIT_QDEV(eth_dev) (eth_dev->data->dev_private)
#define QEDE_INIT_EDEV(adapter) (&((struct qede_dev *)adapter)->edev)
#define QEDE_INIT(eth_dev) { \
struct qede_dev *qdev = eth_dev->data->dev_private; \
struct ecore_dev *edev = &qdev->edev; \
}
/************* QLogic 25G/40G vendor/devices ids *************/
#define PCI_VENDOR_ID_QLOGIC 0x1077
#define CHIP_NUM_57980E 0x1634
#define CHIP_NUM_57980S 0x1629
#define CHIP_NUM_VF 0x1630
#define CHIP_NUM_57980S_40 0x1634
#define CHIP_NUM_57980S_25 0x1656
#define CHIP_NUM_57980S_IOV 0x1664
#define PCI_DEVICE_ID_NX2_57980E CHIP_NUM_57980E
#define PCI_DEVICE_ID_NX2_57980S CHIP_NUM_57980S
#define PCI_DEVICE_ID_NX2_VF CHIP_NUM_VF
#define PCI_DEVICE_ID_57980S_40 CHIP_NUM_57980S_40
#define PCI_DEVICE_ID_57980S_25 CHIP_NUM_57980S_25
#define PCI_DEVICE_ID_57980S_IOV CHIP_NUM_57980S_IOV
extern char fw_file[];
/* Port/function states */
enum dev_state {
QEDE_START,
QEDE_STOP,
QEDE_CLOSE
};
struct qed_int_param {
uint32_t int_mode;
uint8_t num_vectors;
uint8_t min_msix_cnt;
};
struct qed_int_params {
struct qed_int_param in;
struct qed_int_param out;
bool fp_initialized;
};
/*
* Structure to store private data for each port.
*/
struct qede_dev {
struct ecore_dev edev;
uint8_t protocol;
const struct qed_eth_ops *ops;
struct qed_dev_eth_info dev_info;
struct ecore_sb_info *sb_array;
struct qede_fastpath *fp_array;
uint16_t num_rss;
uint8_t num_tc;
uint16_t mtu;
bool rss_enabled;
struct qed_update_vport_rss_params rss_params;
uint32_t flags;
bool gro_disable;
struct qede_rx_queue **rx_queues;
struct qede_tx_queue **tx_queues;
enum dev_state state;
/* Vlans */
osal_list_t vlan_list;
uint16_t configured_vlans;
uint16_t non_configured_vlans;
bool accept_any_vlan;
uint16_t vxlan_dst_port;
struct ether_addr primary_mac;
bool handle_hw_err;
char drv_ver[QED_DRV_VER_STR_SIZE];
};
int qed_fill_eth_dev_info(struct ecore_dev *edev,
struct qed_dev_eth_info *info);
int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up);
void qede_config_rx_mode(struct rte_eth_dev *eth_dev);
#endif /* _QEDE_ETHDEV_H_ */

155
drivers/net/qede/qede_if.h Normal file
View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2016 QLogic Corporation.
* All rights reserved.
* www.qlogic.com
*
* See LICENSE.qede_pmd for copyright and licensing details.
*/
#ifndef _QEDE_IF_H
#define _QEDE_IF_H
#include "qede_ethdev.h"
/* forward */
struct ecore_dev;
struct qed_sb_info;
struct qed_pf_params;
enum ecore_int_mode;
struct qed_dev_info {
uint8_t num_hwfns;
uint8_t hw_mac[ETHER_ADDR_LEN];
bool is_mf_default;
/* FW version */
uint16_t fw_major;
uint16_t fw_minor;
uint16_t fw_rev;
uint16_t fw_eng;
/* MFW version */
uint32_t mfw_rev;
uint32_t flash_size;
uint8_t mf_mode;
bool tx_switching;
/* To be added... */
};
enum qed_sb_type {
QED_SB_TYPE_L2_QUEUE,
QED_SB_TYPE_STORAGE,
QED_SB_TYPE_CNQ,
};
enum qed_protocol {
QED_PROTOCOL_ETH,
};
struct qed_link_params {
bool link_up;
#define QED_LINK_OVERRIDE_SPEED_AUTONEG (1 << 0)
#define QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS (1 << 1)
#define QED_LINK_OVERRIDE_SPEED_FORCED_SPEED (1 << 2)
#define QED_LINK_OVERRIDE_PAUSE_CONFIG (1 << 3)
uint32_t override_flags;
bool autoneg;
uint32_t adv_speeds;
uint32_t forced_speed;
#define QED_LINK_PAUSE_AUTONEG_ENABLE (1 << 0)
#define QED_LINK_PAUSE_RX_ENABLE (1 << 1)
#define QED_LINK_PAUSE_TX_ENABLE (1 << 2)
uint32_t pause_config;
};
struct qed_link_output {
bool link_up;
uint32_t supported_caps; /* In SUPPORTED defs */
uint32_t advertised_caps; /* In ADVERTISED defs */
uint32_t lp_caps; /* In ADVERTISED defs */
uint32_t speed; /* In Mb/s */
uint8_t duplex; /* In DUPLEX defs */
uint8_t port; /* In PORT defs */
bool autoneg;
uint32_t pause_config;
};
#define QED_DRV_VER_STR_SIZE 80
struct qed_slowpath_params {
uint32_t int_mode;
uint8_t drv_major;
uint8_t drv_minor;
uint8_t drv_rev;
uint8_t drv_eng;
uint8_t name[QED_DRV_VER_STR_SIZE];
};
#define ILT_PAGE_SIZE_TCFC 0x8000 /* 32KB */
struct qed_common_cb_ops {
void (*link_update)(void *dev, struct qed_link_output *link);
};
struct qed_selftest_ops {
/**
* @brief registers - Perform register tests
*
* @param edev
*
* @return 0 on success, error otherwise.
*/
int (*registers)(struct ecore_dev *edev);
};
struct qed_common_ops {
int (*probe)(struct ecore_dev *edev,
struct rte_pci_device *pci_dev,
enum qed_protocol protocol,
uint32_t dp_module, uint8_t dp_level, bool is_vf);
void (*set_id)(struct ecore_dev *edev,
char name[], const char ver_str[]);
enum _ecore_status_t (*chain_alloc)(struct ecore_dev *edev,
enum ecore_chain_use_mode
intended_use,
enum ecore_chain_mode mode,
enum ecore_chain_cnt_type cnt_type,
uint32_t num_elems,
osal_size_t elem_size,
struct ecore_chain *p_chain);
void (*chain_free)(struct ecore_dev *edev,
struct ecore_chain *p_chain);
void (*get_link)(struct ecore_dev *edev,
struct qed_link_output *if_link);
int (*set_link)(struct ecore_dev *edev,
struct qed_link_params *params);
int (*drain)(struct ecore_dev *edev);
void (*remove)(struct ecore_dev *edev);
int (*slowpath_stop)(struct ecore_dev *edev);
void (*update_pf_params)(struct ecore_dev *edev,
struct ecore_pf_params *params);
int (*slowpath_start)(struct ecore_dev *edev,
struct qed_slowpath_params *params);
int (*set_fp_int)(struct ecore_dev *edev, uint16_t cnt);
uint32_t (*sb_init)(struct ecore_dev *edev,
struct ecore_sb_info *sb_info,
void *sb_virt_addr,
dma_addr_t sb_phy_addr,
uint16_t sb_id, enum qed_sb_type type);
bool (*can_link_change)(struct ecore_dev *edev);
void (*update_msglvl)(struct ecore_dev *edev,
uint32_t dp_module, uint8_t dp_level);
};
#endif /* _QEDE_IF_H */

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2016 QLogic Corporation.
* All rights reserved.
* www.qlogic.com
*
* See LICENSE.qede_pmd for copyright and licensing details.
*/
#ifndef _QEDE_LOGS_H_
#define _QEDE_LOGS_H_
#define DP_ERR(p_dev, fmt, ...) \
rte_log(RTE_LOG_ERR, RTE_LOGTYPE_PMD, \
"[%s:%d(%s)]" fmt, \
__func__, __LINE__, \
(p_dev)->name ? (p_dev)->name : "", \
##__VA_ARGS__)
#define DP_NOTICE(p_dev, is_assert, fmt, ...) \
rte_log(RTE_LOG_NOTICE, RTE_LOGTYPE_PMD,\
"[QEDE PMD: (%s)]%s:" fmt, \
(p_dev)->name ? (p_dev)->name : "", \
__func__, \
##__VA_ARGS__)
#ifdef RTE_LIBRTE_QEDE_DEBUG_INFO
#define DP_INFO(p_dev, fmt, ...) \
rte_log(RTE_LOG_INFO, RTE_LOGTYPE_PMD, \
"[%s:%d(%s)]" fmt, \
__func__, __LINE__, \
(p_dev)->name ? (p_dev)->name : "", \
##__VA_ARGS__)
#else
#define DP_INFO(p_dev, fmt, ...) do { } while (0)
#endif
#ifdef RTE_LIBRTE_QEDE_DEBUG_DRV
#define DP_VERBOSE(p_dev, module, fmt, ...) \
do { \
if ((p_dev)->dp_module & module) \
rte_log(RTE_LOG_DEBUG, RTE_LOGTYPE_PMD, \
"[%s:%d(%s)]" fmt, \
__func__, __LINE__, \
(p_dev)->name ? (p_dev)->name : "", \
##__VA_ARGS__); \
} while (0)
#else
#define DP_VERBOSE(p_dev, fmt, ...) do { } while (0)
#endif
#define PMD_INIT_LOG(level, edev, fmt, args...) \
rte_log(RTE_LOG_ ## level, RTE_LOGTYPE_PMD, \
"[qede_pmd: %s] %s() " fmt "\n", \
(edev)->name, __func__, ##args)
#ifdef RTE_LIBRTE_QEDE_DEBUG_INIT
#define PMD_INIT_FUNC_TRACE(edev) PMD_INIT_LOG(DEBUG, edev, " >>")
#else
#define PMD_INIT_FUNC_TRACE(edev) do { } while (0)
#endif
#ifdef RTE_LIBRTE_QEDE_DEBUG_TX
#define PMD_TX_LOG(level, q, fmt, args...) \
RTE_LOG(level, PMD, "%s(): port=%u queue=%u " fmt "\n", \
__func__, q->port_id, q->queue_id, ## args)
#else
#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
#endif
#ifdef RTE_LIBRTE_QEDE_DEBUG_RX
#define PMD_RX_LOG(level, q, fmt, args...) \
RTE_LOG(level, PMD, "%s(): port=%u queue=%u " fmt "\n", \
__func__, q->port_id, q->queue_id, ## args)
#else
#define PMD_RX_LOG(level, q, fmt, args...) do { } while (0)
#endif
#ifdef RTE_LIBRTE_QEDE_DEBUG_DRIVER
#define PMD_DRV_LOG_RAW(level, fmt, args...) \
RTE_LOG(level, PMD, "%s(): " fmt, __func__, ## args)
#else
#define PMD_DRV_LOG_RAW(level, fmt, args...) do { } while (0)
#endif
#define PMD_DRV_LOG(level, fmt, args...) \
PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
#endif /* _QEDE_LOGS_H_ */

View File

@ -0,0 +1,545 @@
/*
* Copyright (c) 2016 QLogic Corporation.
* All rights reserved.
* www.qlogic.com
*
* See LICENSE.qede_pmd for copyright and licensing details.
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <zlib.h>
#include <limits.h>
#include "qede_ethdev.h"
static uint8_t npar_tx_switching = 1;
#define CONFIG_QED_BINARY_FW
/* Global variable to hold absolute path of fw file */
char fw_file[PATH_MAX];
const char *QEDE_DEFAULT_FIRMWARE =
"/lib/firmware/qed/qed_init_values_zipped-8.7.7.0.bin";
static void
qed_update_pf_params(struct ecore_dev *edev, struct ecore_pf_params *params)
{
int i;
for (i = 0; i < edev->num_hwfns; i++) {
struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
p_hwfn->pf_params = *params;
}
}
static void qed_init_pci(struct ecore_dev *edev, struct rte_pci_device *pci_dev)
{
edev->regview = pci_dev->mem_resource[0].addr;
edev->doorbells = pci_dev->mem_resource[2].addr;
}
static int
qed_probe(struct ecore_dev *edev, struct rte_pci_device *pci_dev,
enum qed_protocol protocol, uint32_t dp_module,
uint8_t dp_level, bool is_vf)
{
struct qede_dev *qdev = (struct qede_dev *)edev;
int rc;
ecore_init_struct(edev);
qdev->protocol = protocol;
if (is_vf) {
edev->b_is_vf = true;
edev->sriov_info.b_hw_channel = true;
}
ecore_init_dp(edev, dp_module, dp_level, NULL);
qed_init_pci(edev, pci_dev);
rc = ecore_hw_prepare(edev, ECORE_PCI_DEFAULT);
if (rc) {
DP_ERR(edev, "hw prepare failed\n");
return rc;
}
return rc;
}
static int qed_nic_setup(struct ecore_dev *edev)
{
int rc, i;
rc = ecore_resc_alloc(edev);
if (rc)
return rc;
DP_INFO(edev, "Allocated qed resources\n");
ecore_resc_setup(edev);
return rc;
}
static int qed_alloc_stream_mem(struct ecore_dev *edev)
{
int i;
for_each_hwfn(edev, i) {
struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
p_hwfn->stream = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
sizeof(*p_hwfn->stream));
if (!p_hwfn->stream)
return -ENOMEM;
}
return 0;
}
static void qed_free_stream_mem(struct ecore_dev *edev)
{
int i;
for_each_hwfn(edev, i) {
struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
if (!p_hwfn->stream)
return;
OSAL_FREE(p_hwfn->p_dev, p_hwfn->stream);
}
}
static int qed_load_firmware_data(struct ecore_dev *edev)
{
int fd;
struct stat st;
const char *fw = RTE_LIBRTE_QEDE_FW;
if (strcmp(fw, "") == 0)
strcpy(fw_file, QEDE_DEFAULT_FIRMWARE);
else
strcpy(fw_file, fw);
fd = open(fw_file, O_RDONLY);
if (fd < 0) {
DP_NOTICE(edev, false, "Can't open firmware file\n");
return -ENOENT;
}
if (fstat(fd, &st) < 0) {
DP_NOTICE(edev, false, "Can't stat firmware file\n");
return -1;
}
edev->firmware = rte_zmalloc("qede_fw", st.st_size,
RTE_CACHE_LINE_SIZE);
if (!edev->firmware) {
DP_NOTICE(edev, false, "Can't allocate memory for firmware\n");
close(fd);
return -ENOMEM;
}
if (read(fd, edev->firmware, st.st_size) != st.st_size) {
DP_NOTICE(edev, false, "Can't read firmware data\n");
close(fd);
return -1;
}
edev->fw_len = st.st_size;
if (edev->fw_len < 104) {
DP_NOTICE(edev, false, "Invalid fw size: %" PRIu64 "\n",
edev->fw_len);
return -EINVAL;
}
return 0;
}
static int qed_slowpath_start(struct ecore_dev *edev,
struct qed_slowpath_params *params)
{
bool allow_npar_tx_switching;
const uint8_t *data = NULL;
struct ecore_hwfn *hwfn;
struct ecore_mcp_drv_version drv_version;
struct qede_dev *qdev = (struct qede_dev *)edev;
int rc;
#ifdef QED_ENC_SUPPORTED
struct ecore_tunn_start_params tunn_info;
#endif
#ifdef CONFIG_QED_BINARY_FW
rc = qed_load_firmware_data(edev);
if (rc) {
DP_NOTICE(edev, true,
"Failed to find fw file %s\n", fw_file);
goto err;
}
#endif
rc = qed_nic_setup(edev);
if (rc)
goto err;
/* set int_coalescing_mode */
edev->int_coalescing_mode = ECORE_COAL_MODE_ENABLE;
/* Should go with CONFIG_QED_BINARY_FW */
/* Allocate stream for unzipping */
rc = qed_alloc_stream_mem(edev);
if (rc) {
DP_NOTICE(edev, true,
"Failed to allocate stream memory\n");
goto err2;
}
/* Start the slowpath */
#ifdef CONFIG_QED_BINARY_FW
data = edev->firmware;
#endif
allow_npar_tx_switching = npar_tx_switching ? true : false;
#ifdef QED_ENC_SUPPORTED
memset(&tunn_info, 0, sizeof(tunn_info));
tunn_info.tunn_mode |= 1 << QED_MODE_VXLAN_TUNN |
1 << QED_MODE_L2GRE_TUNN |
1 << QED_MODE_IPGRE_TUNN |
1 << QED_MODE_L2GENEVE_TUNN | 1 << QED_MODE_IPGENEVE_TUNN;
tunn_info.tunn_clss_vxlan = QED_TUNN_CLSS_MAC_VLAN;
tunn_info.tunn_clss_l2gre = QED_TUNN_CLSS_MAC_VLAN;
tunn_info.tunn_clss_ipgre = QED_TUNN_CLSS_MAC_VLAN;
rc = ecore_hw_init(edev, &tunn_info, true, ECORE_INT_MODE_MSIX,
allow_npar_tx_switching, data);
#else
rc = ecore_hw_init(edev, NULL, true, ECORE_INT_MODE_MSIX,
allow_npar_tx_switching, data);
#endif
if (rc) {
DP_ERR(edev, "ecore_hw_init failed\n");
goto err2;
}
DP_INFO(edev, "HW inited and function started\n");
hwfn = ECORE_LEADING_HWFN(edev);
drv_version.version = (params->drv_major << 24) |
(params->drv_minor << 16) |
(params->drv_rev << 8) | (params->drv_eng);
/* TBD: strlcpy() */
strncpy((char *)drv_version.name, (const char *)params->name,
MCP_DRV_VER_STR_SIZE - 4);
rc = ecore_mcp_send_drv_version(hwfn, hwfn->p_main_ptt,
&drv_version);
if (rc) {
DP_NOTICE(edev, true,
"Failed sending drv version command\n");
return rc;
}
return 0;
ecore_hw_stop(edev);
err2:
ecore_resc_free(edev);
err:
#ifdef CONFIG_QED_BINARY_FW
if (edev->firmware)
rte_free(edev->firmware);
edev->firmware = NULL;
#endif
return rc;
}
static int
qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info)
{
struct ecore_ptt *ptt = NULL;
memset(dev_info, 0, sizeof(struct qed_dev_info));
dev_info->num_hwfns = edev->num_hwfns;
dev_info->is_mf_default = IS_MF_DEFAULT(&edev->hwfns[0]);
rte_memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
ETHER_ADDR_LEN);
dev_info->fw_major = FW_MAJOR_VERSION;
dev_info->fw_minor = FW_MINOR_VERSION;
dev_info->fw_rev = FW_REVISION_VERSION;
dev_info->fw_eng = FW_ENGINEERING_VERSION;
dev_info->mf_mode = edev->mf_mode;
dev_info->tx_switching = false;
ptt = ecore_ptt_acquire(ECORE_LEADING_HWFN(edev));
if (ptt) {
ecore_mcp_get_mfw_ver(edev, ptt,
&dev_info->mfw_rev, NULL);
ecore_mcp_get_flash_size(ECORE_LEADING_HWFN(edev), ptt,
&dev_info->flash_size);
/* Workaround to allow PHY-read commands for
* B0 bringup.
*/
if (ECORE_IS_BB_B0(edev))
dev_info->flash_size = 0xffffffff;
ecore_ptt_release(ECORE_LEADING_HWFN(edev), ptt);
}
return 0;
}
int
qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
{
struct qede_dev *qdev = (struct qede_dev *)edev;
int i;
memset(info, 0, sizeof(*info));
info->num_tc = 1 /* @@@TBD aelior MULTI_COS */;
info->num_queues = 0;
for_each_hwfn(edev, i)
info->num_queues +=
FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE);
info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN);
rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
ETHER_ADDR_LEN);
qed_fill_dev_info(edev, &info->common);
return 0;
}
static void
qed_set_id(struct ecore_dev *edev, char name[NAME_SIZE],
const char ver_str[VER_SIZE])
{
int i;
rte_memcpy(edev->name, name, NAME_SIZE);
for_each_hwfn(edev, i) {
snprintf(edev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i);
}
rte_memcpy(edev->ver_str, ver_str, VER_SIZE);
edev->drv_type = DRV_ID_DRV_TYPE_LINUX;
}
static uint32_t
qed_sb_init(struct ecore_dev *edev, struct ecore_sb_info *sb_info,
void *sb_virt_addr, dma_addr_t sb_phy_addr,
uint16_t sb_id, enum qed_sb_type type)
{
struct ecore_hwfn *p_hwfn;
int hwfn_index;
uint16_t rel_sb_id;
uint8_t n_hwfns;
uint32_t rc;
/* RoCE uses single engine and CMT uses two engines. When using both
* we force only a single engine. Storage uses only engine 0 too.
*/
if (type == QED_SB_TYPE_L2_QUEUE)
n_hwfns = edev->num_hwfns;
else
n_hwfns = 1;
hwfn_index = sb_id % n_hwfns;
p_hwfn = &edev->hwfns[hwfn_index];
rel_sb_id = sb_id / n_hwfns;
DP_INFO(edev, "hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n",
hwfn_index, rel_sb_id, sb_id);
rc = ecore_int_sb_init(p_hwfn, p_hwfn->p_main_ptt, sb_info,
sb_virt_addr, sb_phy_addr, rel_sb_id);
return rc;
}
static void qed_fill_link(struct ecore_hwfn *hwfn,
struct qed_link_output *if_link)
{
struct ecore_mcp_link_params params;
struct ecore_mcp_link_state link;
struct ecore_mcp_link_capabilities link_caps;
uint32_t media_type;
uint8_t change = 0;
memset(if_link, 0, sizeof(*if_link));
/* Prepare source inputs */
rte_memcpy(&params, ecore_mcp_get_link_params(hwfn),
sizeof(params));
rte_memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link));
rte_memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn),
sizeof(link_caps));
/* Set the link parameters to pass to protocol driver */
if (link.link_up)
if_link->link_up = true;
if (link.link_up)
if_link->speed = link.speed;
if_link->duplex = QEDE_DUPLEX_FULL;
if (params.speed.autoneg)
if_link->supported_caps |= QEDE_SUPPORTED_AUTONEG;
if (params.pause.autoneg || params.pause.forced_rx ||
params.pause.forced_tx)
if_link->supported_caps |= QEDE_SUPPORTED_PAUSE;
if (params.pause.autoneg)
if_link->pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
if (params.pause.forced_rx)
if_link->pause_config |= QED_LINK_PAUSE_RX_ENABLE;
if (params.pause.forced_tx)
if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE;
}
static void
qed_get_current_link(struct ecore_dev *edev, struct qed_link_output *if_link)
{
qed_fill_link(&edev->hwfns[0], if_link);
#ifdef CONFIG_QED_SRIOV
for_each_hwfn(cdev, i)
qed_inform_vf_link_state(&cdev->hwfns[i]);
#endif
}
static int qed_set_link(struct ecore_dev *edev, struct qed_link_params *params)
{
struct ecore_hwfn *hwfn;
struct ecore_ptt *ptt;
struct ecore_mcp_link_params *link_params;
int rc;
/* The link should be set only once per PF */
hwfn = &edev->hwfns[0];
ptt = ecore_ptt_acquire(hwfn);
if (!ptt)
return -EBUSY;
link_params = ecore_mcp_get_link_params(hwfn);
if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
link_params->speed.autoneg = params->autoneg;
if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) {
if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
link_params->pause.autoneg = true;
else
link_params->pause.autoneg = false;
if (params->pause_config & QED_LINK_PAUSE_RX_ENABLE)
link_params->pause.forced_rx = true;
else
link_params->pause.forced_rx = false;
if (params->pause_config & QED_LINK_PAUSE_TX_ENABLE)
link_params->pause.forced_tx = true;
else
link_params->pause.forced_tx = false;
}
rc = ecore_mcp_set_link(hwfn, ptt, params->link_up);
ecore_ptt_release(hwfn, ptt);
return rc;
}
static int qed_drain(struct ecore_dev *edev)
{
struct ecore_hwfn *hwfn;
struct ecore_ptt *ptt;
int i, rc;
for_each_hwfn(edev, i) {
hwfn = &edev->hwfns[i];
ptt = ecore_ptt_acquire(hwfn);
if (!ptt) {
DP_NOTICE(hwfn, true, "Failed to drain NIG; No PTT\n");
return -EBUSY;
}
rc = ecore_mcp_drain(hwfn, ptt);
if (rc)
return rc;
ecore_ptt_release(hwfn, ptt);
}
return 0;
}
static int qed_nic_stop(struct ecore_dev *edev)
{
int i, rc;
rc = ecore_hw_stop(edev);
for (i = 0; i < edev->num_hwfns; i++) {
struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
if (p_hwfn->b_sp_dpc_enabled)
p_hwfn->b_sp_dpc_enabled = false;
}
return rc;
}
static int qed_nic_reset(struct ecore_dev *edev)
{
int rc;
rc = ecore_hw_reset(edev);
if (rc)
return rc;
ecore_resc_free(edev);
return 0;
}
static int qed_slowpath_stop(struct ecore_dev *edev)
{
#ifdef CONFIG_QED_SRIOV
int i;
#endif
if (!edev)
return -ENODEV;
qed_free_stream_mem(edev);
qed_nic_stop(edev);
qed_nic_reset(edev);
return 0;
}
static void qed_remove(struct ecore_dev *edev)
{
if (!edev)
return;
ecore_hw_remove(edev);
}
const struct qed_common_ops qed_common_ops_pass = {
INIT_STRUCT_FIELD(probe, &qed_probe),
INIT_STRUCT_FIELD(update_pf_params, &qed_update_pf_params),
INIT_STRUCT_FIELD(slowpath_start, &qed_slowpath_start),
INIT_STRUCT_FIELD(set_id, &qed_set_id),
INIT_STRUCT_FIELD(chain_alloc, &ecore_chain_alloc),
INIT_STRUCT_FIELD(chain_free, &ecore_chain_free),
INIT_STRUCT_FIELD(sb_init, &qed_sb_init),
INIT_STRUCT_FIELD(get_link, &qed_get_current_link),
INIT_STRUCT_FIELD(set_link, &qed_set_link),
INIT_STRUCT_FIELD(drain, &qed_drain),
INIT_STRUCT_FIELD(slowpath_stop, &qed_slowpath_stop),
INIT_STRUCT_FIELD(remove, &qed_remove),
};

1192
drivers/net/qede/qede_rxtx.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,179 @@
/*
* Copyright (c) 2016 QLogic Corporation.
* All rights reserved.
* www.qlogic.com
*
* See LICENSE.qede_pmd for copyright and licensing details.
*/
#ifndef _QEDE_RXTX_H_
#define _QEDE_RXTX_H_
#include "qede_ethdev.h"
/* Ring Descriptors */
#define RX_RING_SIZE_POW 16 /* 64K */
#define RX_RING_SIZE (1ULL << RX_RING_SIZE_POW)
#define NUM_RX_BDS_MAX (RX_RING_SIZE - 1)
#define NUM_RX_BDS_MIN 128
#define NUM_RX_BDS_DEF NUM_RX_BDS_MAX
#define NUM_RX_BDS(q) (q->nb_rx_desc - 1)
#define TX_RING_SIZE_POW 16 /* 64K */
#define TX_RING_SIZE (1ULL << TX_RING_SIZE_POW)
#define NUM_TX_BDS_MAX (TX_RING_SIZE - 1)
#define NUM_TX_BDS_MIN 128
#define NUM_TX_BDS_DEF NUM_TX_BDS_MAX
#define NUM_TX_BDS(q) (q->nb_tx_desc - 1)
#define TX_CONS(txq) (txq->sw_tx_cons & NUM_TX_BDS(txq))
#define TX_PROD(txq) (txq->sw_tx_prod & NUM_TX_BDS(txq))
/* Number of TX BDs per packet used currently */
#define MAX_NUM_TX_BDS 1
#define QEDE_DEFAULT_TX_FREE_THRESH 32
#define QEDE_CSUM_ERROR (1 << 0)
#define QEDE_CSUM_UNNECESSARY (1 << 1)
#define QEDE_TUNN_CSUM_UNNECESSARY (1 << 2)
#define QEDE_BD_SET_ADDR_LEN(bd, maddr, len) \
do { \
(bd)->addr.hi = rte_cpu_to_le_32(U64_HI(maddr)); \
(bd)->addr.lo = rte_cpu_to_le_32(U64_LO(maddr)); \
(bd)->nbytes = rte_cpu_to_le_16(len); \
} while (0)
#define CQE_HAS_VLAN(flags) \
((flags) & (PARSING_AND_ERR_FLAGS_TAG8021QEXIST_MASK \
<< PARSING_AND_ERR_FLAGS_TAG8021QEXIST_SHIFT))
#define CQE_HAS_OUTER_VLAN(flags) \
((flags) & (PARSING_AND_ERR_FLAGS_TUNNEL8021QTAGEXIST_MASK \
<< PARSING_AND_ERR_FLAGS_TUNNEL8021QTAGEXIST_SHIFT))
/* Max supported alignment is 256 (8 shift)
* minimal alignment shift 6 is optimal for 57xxx HW performance
*/
#define QEDE_L1_CACHE_SHIFT 6
#define QEDE_RX_ALIGN_SHIFT (RTE_MAX(6, RTE_MIN(8, QEDE_L1_CACHE_SHIFT)))
#define QEDE_FW_RX_ALIGN_END (1UL << QEDE_RX_ALIGN_SHIFT)
#define QEDE_ETH_OVERHEAD (ETHER_HDR_LEN + 8 + 8 + QEDE_FW_RX_ALIGN_END)
/* TBD: Excluding IPV6 */
#define QEDE_RSS_OFFLOAD_ALL (ETH_RSS_IPV4 | ETH_RSS_NONFRAG_IPV4_TCP | \
ETH_RSS_NONFRAG_IPV4_UDP)
#define QEDE_TXQ_FLAGS ((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS)
#define MAX_NUM_TC 8
#define for_each_rss(i) for (i = 0; i < qdev->num_rss; i++)
/*
* RX BD descriptor ring
*/
struct qede_rx_entry {
struct rte_mbuf *mbuf;
uint32_t page_offset;
/* allows expansion .. */
};
/*
* Structure associated with each RX queue.
*/
struct qede_rx_queue {
struct rte_mempool *mb_pool;
struct ecore_chain rx_bd_ring;
struct ecore_chain rx_comp_ring;
uint16_t *hw_cons_ptr;
void OSAL_IOMEM *hw_rxq_prod_addr;
struct qede_rx_entry *sw_rx_ring;
uint16_t sw_rx_cons;
uint16_t sw_rx_prod;
uint16_t nb_rx_desc;
uint16_t queue_id;
uint16_t port_id;
uint16_t rx_buf_size;
uint64_t rx_hw_errors;
uint64_t rx_alloc_errors;
struct qede_dev *qdev;
};
/*
* TX BD descriptor ring
*/
struct qede_tx_entry {
struct rte_mbuf *mbuf;
uint8_t flags;
};
union db_prod {
struct eth_db_data data;
uint32_t raw;
};
struct qede_tx_queue {
struct ecore_chain tx_pbl;
struct qede_tx_entry *sw_tx_ring;
uint16_t nb_tx_desc;
uint16_t nb_tx_avail;
uint16_t tx_free_thresh;
uint16_t queue_id;
uint16_t *hw_cons_ptr;
uint16_t sw_tx_cons;
uint16_t sw_tx_prod;
void OSAL_IOMEM *doorbell_addr;
volatile union db_prod tx_db;
uint16_t port_id;
uint64_t txq_counter;
struct qede_dev *qdev;
};
struct qede_fastpath {
struct qede_dev *qdev;
uint8_t rss_id;
struct ecore_sb_info *sb_info;
struct qede_rx_queue *rxq;
struct qede_tx_queue *txqs[MAX_NUM_TC];
char name[80];
};
/*
* RX/TX function prototypes
*/
int qede_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 qede_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 qede_rx_queue_release(void *rx_queue);
void qede_tx_queue_release(void *tx_queue);
int qede_dev_start(struct rte_eth_dev *eth_dev);
void qede_dev_stop(struct rte_eth_dev *eth_dev);
void qede_reset_fp_rings(struct qede_dev *qdev);
void qede_free_fp_arrays(struct qede_dev *qdev);
void qede_free_mem_load(struct qede_dev *qdev);
uint16_t qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
uint16_t qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
#endif /* _QEDE_RXTX_H_ */

View File

@ -0,0 +1,4 @@
DPDK_16.04 {
local: *;
};