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:
parent
ec94dbc573
commit
2ea6f76aff
@ -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>
|
||||
|
@ -48,6 +48,7 @@ Network Interface Controller Drivers
|
||||
mlx4
|
||||
mlx5
|
||||
nfp
|
||||
qede
|
||||
szedata2
|
||||
virtio
|
||||
vhost
|
||||
|
@ -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
315
doc/guides/nics/qede.rst
Normal 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.
|
@ -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
|
||||
|
176
drivers/net/qede/qede_eth_if.h
Normal file
176
drivers/net/qede/qede_eth_if.h
Normal 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 */
|
1028
drivers/net/qede/qede_ethdev.c
Normal file
1028
drivers/net/qede/qede_ethdev.c
Normal file
File diff suppressed because it is too large
Load Diff
159
drivers/net/qede/qede_ethdev.h
Normal file
159
drivers/net/qede/qede_ethdev.h
Normal 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
155
drivers/net/qede/qede_if.h
Normal 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 */
|
90
drivers/net/qede/qede_logs.h
Normal file
90
drivers/net/qede/qede_logs.h
Normal 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_ */
|
545
drivers/net/qede/qede_main.c
Normal file
545
drivers/net/qede/qede_main.c
Normal 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(¶ms, 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
1192
drivers/net/qede/qede_rxtx.c
Normal file
File diff suppressed because it is too large
Load Diff
179
drivers/net/qede/qede_rxtx.h
Normal file
179
drivers/net/qede/qede_rxtx.h
Normal 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_ */
|
4
drivers/net/qede/rte_pmd_qede_version.map
Normal file
4
drivers/net/qede/rte_pmd_qede_version.map
Normal file
@ -0,0 +1,4 @@
|
||||
DPDK_16.04 {
|
||||
|
||||
local: *;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user