mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
New driver for Broadcom NetXtreme-C and NetXtreme-E devices.
This driver uses the iflib framework supporting Broadcom 25/50Gbps devices. Reviewed by: gallatin, wblock Approved by: davidch MFC after: 2 weeks Relnotes: yes Sponsored by: Broadcom Limited Differential Revision: https://reviews.freebsd.org/D7551
This commit is contained in:
parent
ba3eb10d85
commit
d933e97f9d
17 changed files with 24183 additions and 0 deletions
|
|
@ -79,6 +79,7 @@ MAN= aac.4 \
|
|||
bhndb.4 \
|
||||
bktr.4 \
|
||||
blackhole.4 \
|
||||
bnxt.4 \
|
||||
bpf.4 \
|
||||
bridge.4 \
|
||||
bt.4 \
|
||||
|
|
@ -592,6 +593,7 @@ MLINKS+=bce.4 if_bce.4
|
|||
MLINKS+=bfe.4 if_bfe.4
|
||||
MLINKS+=bge.4 if_bge.4
|
||||
MLINKS+=bktr.4 brooktree.4
|
||||
MLINKS+=bnxt.4 if_bnxt.4
|
||||
MLINKS+=bridge.4 if_bridge.4
|
||||
MLINKS+=bwi.4 if_bwi.4
|
||||
MLINKS+=bwn.4 if_bwn.4
|
||||
|
|
|
|||
222
share/man/man4/bnxt.4
Normal file
222
share/man/man4/bnxt.4
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
.\" Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
.\" The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\"
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 12, 2016
|
||||
.Dt BNXT 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm bnxt
|
||||
.Nd "Broadcom NetXtreme-C/NetXtreme-E Family Ethernet driver"
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel,
|
||||
place the following lines in your
|
||||
kernel configuration file:
|
||||
.Bd -ragged -offset indent
|
||||
.Cd "device bnxt"
|
||||
.Ed
|
||||
.Pp
|
||||
Alternatively, to load the driver as a
|
||||
module at boot time, place the following line in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
if_bnxt_load="YES"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for various NICs based on the Broadcom BCM57301/2/4,
|
||||
and BCM57402/4/6 Ethernet controller chips.
|
||||
.Pp
|
||||
For more information on configuring this device, see
|
||||
.Xr ifconfig 8 .
|
||||
.Sh HARDWARE
|
||||
The
|
||||
.Nm
|
||||
driver provides support for various NICs based on the Broadcom NetXtreme-C and
|
||||
NetXtreme-E families of Gigabit Ethernet controller chips, including the
|
||||
following:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
Broadcom BCM57301 NetXtreme-C 10Gb Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57302 NetXtreme-C 10Gb/25Gb Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57304 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57402 NetXtreme-E 10Gb Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57404 NetXtreme-E 10Gb/25Gb Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57406 NetXtreme-E 10GBase-T Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57402 NetXtreme-E Partition
|
||||
.It
|
||||
Broadcom BCM57407 NetXtreme-E 10GBase-T Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57404 NetXtreme-E Partition
|
||||
.It
|
||||
Broadcom BCM57406 NetXtreme-E Partition
|
||||
.It
|
||||
Broadcom BCM57407 NetXtreme-E 25Gb Ethernet Controller
|
||||
.It
|
||||
Broadcom BCM57304 NetXtreme-C Virtual Function
|
||||
.It
|
||||
Broadcom BCM57404 NetXtreme-E Virtual Function
|
||||
.El
|
||||
.Sh SYSCTL VARIABLES
|
||||
These variables must be set before loading the driver, either via
|
||||
.Xr loader.conf 5
|
||||
or through the use of
|
||||
.Xr kenv 1 .
|
||||
These are provided by the
|
||||
.Xr iflib 9
|
||||
framework, and might be better documented there.
|
||||
.Bl -tag -width indent
|
||||
.It Va dev.bnxt.X.iflib.override_nrxds
|
||||
Override the number of RX descriptors for each queue.
|
||||
The value is a comma separated list of three positive integers: the size of the
|
||||
completion ring,
|
||||
the size of the receive ring, and the size of the aggregation ring respectively.
|
||||
The completion ring should be at least the size of the aggregation ring plus
|
||||
four times the size of the receive ring.
|
||||
These numbers must be powers of two, and zero means to use the default.
|
||||
Defaults to 0,0,0.
|
||||
.It Va dev.bnxt.X.iflib.override_ntxds
|
||||
Override the number of TX descriptors for each queue.
|
||||
The value is a comma separated list of two positive integers: the size of the
|
||||
completion ring, and the size of the transmit ring respectively.
|
||||
The completion ring should be at least twice the size of the transmit ring.
|
||||
These numbers must be powers of two, and zero means to use the default.
|
||||
Defaults to 0,0.
|
||||
.It Va override_qs_enable
|
||||
When set, allows the number of transmit and receive queues to be different.
|
||||
If not set, the lower of the number of TX or RX queues will be used for both.
|
||||
.It Va override_nrxqs
|
||||
Set the number of RX queues.
|
||||
If zero, the number of RX queues is derived from the number of cores on the
|
||||
socket connected to the controller.
|
||||
Defaults to 0.
|
||||
.It Va override_ntxqs
|
||||
Set the number of TX queues.
|
||||
If zero, the number of TX queues is derived from the number of cores on the
|
||||
socket connected to the controller.
|
||||
.El
|
||||
.Pp
|
||||
These
|
||||
.Xr sysctl 8
|
||||
variables can be changed at any time:
|
||||
.Bl -tag -width indent
|
||||
.It Va dev.bnxt.X.vlan_only
|
||||
Require that incoming frames must have a VLAN tag on them that matches one that
|
||||
is configured for the NIC.
|
||||
Normally, both frames that have a matching VLAN tag and frames that have no
|
||||
VLAN tag are accepted.
|
||||
Defaults to 0.
|
||||
.It Va dev.bnxt.X.vlan_strip
|
||||
When non-zero the NIC strips VLAN tags on receive.
|
||||
Defaults to 0.
|
||||
.It Va dev.bnxt.X.rx_stall
|
||||
Enable buffering rather than dropping frames when there are no available host
|
||||
RX buffers for DMA.
|
||||
Defaults to 0.
|
||||
.It Va dev.bnxt.X.rss_type
|
||||
Comma-separated list of RSS hash types to support.
|
||||
Default is all types.
|
||||
Defaults to ipv4,tcp_ipv4,udp_ipv4,ipv6,tcp_ipv6,udp_ipv6.
|
||||
.It Va dev.bnxt.X.rss_key
|
||||
Current RSS key.
|
||||
Defaults to a randomly generated value which is generated for each device
|
||||
during attach.
|
||||
.It Va dev.bnxt.X.ver.hwrm_min_ver
|
||||
Minimum HWRM (HardWare Resource Manager) firmware API to support.
|
||||
If the firmware implements an older version, a warning will be printed, and the
|
||||
firmware should be upgraded.
|
||||
Defaults to 1.2.2.
|
||||
.El
|
||||
.Pp
|
||||
These
|
||||
.Xr sysctl 8
|
||||
variables are read-only:
|
||||
.Bl -tag -width indent
|
||||
.It Va dev.bnxt.X.if_name
|
||||
Current interface name of the device.
|
||||
This will normally be
|
||||
.Va bnxtX ,
|
||||
but this can be changed using
|
||||
.Cm ifconfig name .
|
||||
This sysctl allows correlating an interface with a child of dev.bnxt.
|
||||
.It Va dev.bnxt.X.nvram.*
|
||||
Information about the NVRAM device which contains the device firmware.
|
||||
.It Va dev.bnxt.X.ver.*
|
||||
Version-related information about the device and firmware:
|
||||
.It Va dev.bnxt.X.ver.hwrm_if
|
||||
Supported HWRM API version of the currently running firmware.
|
||||
.It Va dev.bnxt.X.ver.driver_hwrm_if
|
||||
HWRM API version the driver was built to support.
|
||||
.It Va dev.bnxt.X.hwstats.*
|
||||
Per-queue statistics tracked by the hardware.
|
||||
.It Va dev.bnxt.X.hwstats.rxq0.drop_pkts
|
||||
Number of packets dropped by hardware on queue zero.
|
||||
This number might seem high, but the count includes packets dropped due to
|
||||
incorrect destination MAC, unsubscribed multicast address, and other normal
|
||||
reasons to ignore Ethernet frames.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
.Bl -diag
|
||||
.It "bnxt%d: %s command returned %s error."
|
||||
Device firmware rejected a command from the driver.
|
||||
There might be a driver/firmware HWRM API mismatch.
|
||||
.It "bnxt%d: Timeout sending %s (timeout: %d) seq %d\n"
|
||||
Device firmware unresponsive.
|
||||
A PCI device reset is likely needed.
|
||||
.It "bnxt%d: Timeout sending %s (timeout: %d) msg {0x%x 0x%x} len:%d v: %d\n"
|
||||
Partial firmware response.
|
||||
A PCI device reset is likely needed.
|
||||
.Pp
|
||||
As of this writing, the system must be rebooted to initiate a PCI device reset.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr altq 4 ,
|
||||
.Xr arp 4 ,
|
||||
.Xr netintro 4 ,
|
||||
.Xr ng_ether 4 ,
|
||||
.Xr vlan 4 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr iflib 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
device driver first appeared in
|
||||
.Fx 12.0 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Jack Vogel Aq Mt jfvogel@gmail.com .
|
||||
and is currently maintained by
|
||||
.An Stephen Hurd Aq Mt stephen.hurd@broadcom.com .
|
||||
|
|
@ -312,6 +312,7 @@ if_axe_load="NO" # ASIX Electronics AX88172 USB Ethernet
|
|||
if_bce_load="NO" # Broadcom NetXtreme II Gigabit Ethernet
|
||||
if_bfe_load="NO" # Broadcom BCM4401
|
||||
if_bge_load="NO" # Broadcom BCM570x PCI Gigabit Ethernet
|
||||
if_bnxt_load="NO" # Broadcom NetXtreme-C/NetXtreme-E
|
||||
if_bridge_load="NO" # if_bridge(4) devices
|
||||
if_bwi_load="NO" # Broadcom BCM53xx IEEE 802.11b/g wireness NICs
|
||||
if_bwn_load="NO" # Broadcom BCM43xx IEEE 802.11 wireless NICs
|
||||
|
|
|
|||
|
|
@ -1903,6 +1903,7 @@ device amphy # AMD AM79c873 / Davicom DM910{1,2}
|
|||
device atphy # Attansic/Atheros F1
|
||||
device axphy # Asix Semiconductor AX88x9x
|
||||
device bmtphy # Broadcom BCM5201/BCM5202 and 3Com 3c905C
|
||||
device bnxt # Broadcom NetXtreme-C/NetXtreme-E
|
||||
device brgphy # Broadcom BCM54xx/57xx 1000baseTX
|
||||
device ciphy # Cicada/Vitesse CS/VSC8xxx
|
||||
device e1000phy # Marvell 88E1000 1000/100/10-BT
|
||||
|
|
@ -1943,6 +1944,7 @@ device xmphy # XaQti XMAC II
|
|||
# BCM570x family of controllers, including the 3Com 3c996-T,
|
||||
# the Netgear GA302T, the SysKonnect SK-9D21 and SK-9D41, and
|
||||
# the embedded gigE NICs on Dell PowerEdge 2550 servers.
|
||||
# bnxt: Broadcom NetXtreme-C and NetXtreme-E PCIe 10/25/50G Ethernet adapters.
|
||||
# bxe: Broadcom NetXtreme II (BCM5771X/BCM578XX) PCIe 10Gb Ethernet
|
||||
# adapters.
|
||||
# bwi: Broadcom BCM430* and BCM431* family of wireless adapters.
|
||||
|
|
|
|||
|
|
@ -1242,6 +1242,10 @@ dev/bktr/bktr_i2c.c optional bktr pci smbus
|
|||
dev/bktr/bktr_os.c optional bktr pci
|
||||
dev/bktr/bktr_tuner.c optional bktr pci
|
||||
dev/bktr/msp34xx.c optional bktr pci
|
||||
dev/bnxt/bnxt_hwrm.c optional bnxt iflib pci
|
||||
dev/bnxt/bnxt_sysctl.c optional bnxt iflib pci
|
||||
dev/bnxt/bnxt_txrx.c optional bnxt iflib pci
|
||||
dev/bnxt/if_bnxt.c optional bnxt iflib pci
|
||||
dev/buslogic/bt.c optional bt
|
||||
dev/buslogic/bt_eisa.c optional bt eisa
|
||||
dev/buslogic/bt_isa.c optional bt isa
|
||||
|
|
|
|||
568
sys/dev/bnxt/bnxt.h
Normal file
568
sys/dev/bnxt/bnxt.h
Normal file
|
|
@ -0,0 +1,568 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifndef _BNXT_H
|
||||
#define _BNXT_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/bus_dma.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/taskqueue.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/iflib.h>
|
||||
|
||||
#include "hsi_struct_def.h"
|
||||
|
||||
/* PCI IDs */
|
||||
#define BROADCOM_VENDOR_ID 0x14E4
|
||||
|
||||
#define BCM57301 0x16c8
|
||||
#define BCM57302 0x16c9
|
||||
#define BCM57304 0x16ca
|
||||
#define BCM57402 0x16d0
|
||||
#define BCM57404 0x16d1
|
||||
#define BCM57406 0x16d2
|
||||
#define BCM57402_NPAR 0x16d4
|
||||
#define BCM57407 0x16d5
|
||||
#define BCM57404_NPAR 0x16e7
|
||||
#define BCM57406_NPAR 0x16e8
|
||||
#define BCM57407_SFP 0x16e9
|
||||
#define BCM57304_VF 0x16cb
|
||||
#define BCM57404_VF 0x16d3
|
||||
|
||||
#define CSUM_OFFLOAD (CSUM_IP_TSO|CSUM_IP6_TSO|CSUM_IP| \
|
||||
CSUM_IP_UDP|CSUM_IP_TCP|CSUM_IP_SCTP| \
|
||||
CSUM_IP6_UDP|CSUM_IP6_TCP|CSUM_IP6_SCTP)
|
||||
|
||||
#define BNXT_MAX_MTU 9000
|
||||
|
||||
/* Completion related defines */
|
||||
#define CMP_VALID(cmp, v_bit) \
|
||||
((!!(((struct cmpl_base *)(cmp))->info3_v & htole32(CMPL_BASE_V))) == !!(v_bit) )
|
||||
|
||||
#define NEXT_CP_CONS_V(ring, cons, v_bit) do { \
|
||||
if (__predict_false(++(cons) == (ring)->ring_size)) \
|
||||
((cons) = 0, (v_bit) = !v_bit); \
|
||||
} while (0)
|
||||
|
||||
#define RING_NEXT(ring, idx) (__predict_false(idx + 1 == (ring)->ring_size) ? \
|
||||
0 : idx + 1)
|
||||
|
||||
#define CMPL_PREFETCH_NEXT(cpr, idx) \
|
||||
__builtin_prefetch(&((struct cmpl_base *)(cpr)->ring.vaddr)[((idx) +\
|
||||
(CACHE_LINE_SIZE / sizeof(struct cmpl_base))) & \
|
||||
((cpr)->ring.ring_size - 1)])
|
||||
|
||||
/*
|
||||
* If we update the index, a write barrier is needed after the write to ensure
|
||||
* the completion ring has space before the RX/TX ring does. Since we can't
|
||||
* make the RX and AG doorbells covered by the same barrier without remapping
|
||||
* MSI-X vectors, we create the barrier over the enture doorbell bar.
|
||||
* TODO: Remap the MSI-X vectors to allow a barrier to only cover the doorbells
|
||||
* for a single ring group.
|
||||
*
|
||||
* A barrier of just the size of the write is used to ensure the ordering
|
||||
* remains correct and no writes are lost.
|
||||
*/
|
||||
#define BNXT_CP_DISABLE_DB(ring) do { \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, 4, \
|
||||
BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, 0, \
|
||||
(ring)->softc->doorbell_bar.size, BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_write_4((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, \
|
||||
htole32(CMPL_DOORBELL_KEY_CMPL | CMPL_DOORBELL_MASK)); \
|
||||
} while (0)
|
||||
|
||||
#define BNXT_CP_ENABLE_DB(ring) do { \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, 4, \
|
||||
BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, 0, \
|
||||
(ring)->softc->doorbell_bar.size, BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_write_4((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, \
|
||||
htole32(CMPL_DOORBELL_KEY_CMPL)); \
|
||||
} while (0)
|
||||
|
||||
#define BNXT_CP_IDX_ENABLE_DB(ring, cons) do { \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, 4, \
|
||||
BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_write_4((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, \
|
||||
htole32(CMPL_DOORBELL_KEY_CMPL | CMPL_DOORBELL_IDX_VALID | \
|
||||
(cons))); \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, 0, \
|
||||
(ring)->softc->doorbell_bar.size, BUS_SPACE_BARRIER_WRITE); \
|
||||
} while (0)
|
||||
|
||||
#define BNXT_CP_IDX_DISABLE_DB(ring, cons) do { \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, 4, \
|
||||
BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_write_4((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, \
|
||||
htole32(CMPL_DOORBELL_KEY_CMPL | CMPL_DOORBELL_IDX_VALID | \
|
||||
CMPL_DOORBELL_MASK | (cons))); \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, 0, \
|
||||
(ring)->softc->doorbell_bar.size, BUS_SPACE_BARRIER_WRITE); \
|
||||
} while (0)
|
||||
|
||||
#define BNXT_TX_DB(ring, idx) do { \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, 4, \
|
||||
BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_write_4( \
|
||||
(ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, \
|
||||
(ring)->doorbell, htole32(TX_DOORBELL_KEY_TX | (idx))); \
|
||||
} while (0)
|
||||
|
||||
#define BNXT_RX_DB(ring, idx) do { \
|
||||
bus_space_barrier((ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, (ring)->doorbell, 4, \
|
||||
BUS_SPACE_BARRIER_WRITE); \
|
||||
bus_space_write_4( \
|
||||
(ring)->softc->doorbell_bar.tag, \
|
||||
(ring)->softc->doorbell_bar.handle, \
|
||||
(ring)->doorbell, htole32(RX_DOORBELL_KEY_RX | (idx))); \
|
||||
} while (0)
|
||||
|
||||
/* Lock macros */
|
||||
#define BNXT_HWRM_LOCK_INIT(_softc, _name) \
|
||||
mtx_init(&(_softc)->hwrm_lock, _name, "BNXT HWRM Lock", MTX_DEF)
|
||||
#define BNXT_HWRM_LOCK(_softc) mtx_lock(&(_softc)->hwrm_lock)
|
||||
#define BNXT_HWRM_UNLOCK(_softc) mtx_unlock(&(_softc)->hwrm_lock)
|
||||
#define BNXT_HWRM_LOCK_DESTROY(_softc) mtx_destroy(&(_softc)->hwrm_lock)
|
||||
#define BNXT_HWRM_LOCK_ASSERT(_softc) mtx_assert(&(_softc)->hwrm_lock, \
|
||||
MA_OWNED)
|
||||
|
||||
/* Chip info */
|
||||
#define BNXT_TSO_SIZE UINT16_MAX
|
||||
|
||||
/* NVRAM access */
|
||||
enum bnxt_nvm_directory_type {
|
||||
BNX_DIR_TYPE_UNUSED = 0,
|
||||
BNX_DIR_TYPE_PKG_LOG = 1,
|
||||
BNX_DIR_TYPE_UPDATE = 2,
|
||||
BNX_DIR_TYPE_CHIMP_PATCH = 3,
|
||||
BNX_DIR_TYPE_BOOTCODE = 4,
|
||||
BNX_DIR_TYPE_VPD = 5,
|
||||
BNX_DIR_TYPE_EXP_ROM_MBA = 6,
|
||||
BNX_DIR_TYPE_AVS = 7,
|
||||
BNX_DIR_TYPE_PCIE = 8,
|
||||
BNX_DIR_TYPE_PORT_MACRO = 9,
|
||||
BNX_DIR_TYPE_APE_FW = 10,
|
||||
BNX_DIR_TYPE_APE_PATCH = 11,
|
||||
BNX_DIR_TYPE_KONG_FW = 12,
|
||||
BNX_DIR_TYPE_KONG_PATCH = 13,
|
||||
BNX_DIR_TYPE_BONO_FW = 14,
|
||||
BNX_DIR_TYPE_BONO_PATCH = 15,
|
||||
BNX_DIR_TYPE_TANG_FW = 16,
|
||||
BNX_DIR_TYPE_TANG_PATCH = 17,
|
||||
BNX_DIR_TYPE_BOOTCODE_2 = 18,
|
||||
BNX_DIR_TYPE_CCM = 19,
|
||||
BNX_DIR_TYPE_PCI_CFG = 20,
|
||||
BNX_DIR_TYPE_TSCF_UCODE = 21,
|
||||
BNX_DIR_TYPE_ISCSI_BOOT = 22,
|
||||
BNX_DIR_TYPE_ISCSI_BOOT_IPV6 = 24,
|
||||
BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6 = 25,
|
||||
BNX_DIR_TYPE_ISCSI_BOOT_CFG6 = 26,
|
||||
BNX_DIR_TYPE_EXT_PHY = 27,
|
||||
BNX_DIR_TYPE_SHARED_CFG = 40,
|
||||
BNX_DIR_TYPE_PORT_CFG = 41,
|
||||
BNX_DIR_TYPE_FUNC_CFG = 42,
|
||||
BNX_DIR_TYPE_MGMT_CFG = 48,
|
||||
BNX_DIR_TYPE_MGMT_DATA = 49,
|
||||
BNX_DIR_TYPE_MGMT_WEB_DATA = 50,
|
||||
BNX_DIR_TYPE_MGMT_WEB_META = 51,
|
||||
BNX_DIR_TYPE_MGMT_EVENT_LOG = 52,
|
||||
BNX_DIR_TYPE_MGMT_AUDIT_LOG = 53
|
||||
};
|
||||
|
||||
enum bnxnvm_pkglog_field_index {
|
||||
BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP = 0,
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION = 1,
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_VERSION = 2,
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_TIMESTAMP = 3,
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_CHECKSUM = 4,
|
||||
BNX_PKG_LOG_FIELD_IDX_INSTALLED_ITEMS = 5,
|
||||
BNX_PKG_LOG_FIELD_IDX_INSTALLED_MASK = 6
|
||||
};
|
||||
|
||||
#define BNX_DIR_ORDINAL_FIRST 0
|
||||
#define BNX_DIR_EXT_NONE 0
|
||||
|
||||
struct bnxt_bar_info {
|
||||
struct resource *res;
|
||||
bus_space_tag_t tag;
|
||||
bus_space_handle_t handle;
|
||||
bus_size_t size;
|
||||
int rid;
|
||||
};
|
||||
|
||||
struct bnxt_link_info {
|
||||
uint8_t media_type;
|
||||
uint8_t transceiver;
|
||||
uint8_t phy_addr;
|
||||
uint8_t phy_link_status;
|
||||
uint8_t wire_speed;
|
||||
uint8_t loop_back;
|
||||
uint8_t link_up;
|
||||
uint8_t last_link_up;
|
||||
uint8_t duplex;
|
||||
uint8_t last_duplex;
|
||||
uint8_t pause;
|
||||
uint8_t last_pause;
|
||||
uint8_t auto_pause;
|
||||
uint8_t force_pause;
|
||||
uint8_t duplex_setting;
|
||||
uint8_t auto_mode;
|
||||
#define PHY_VER_LEN 3
|
||||
uint8_t phy_ver[PHY_VER_LEN];
|
||||
uint8_t phy_type;
|
||||
uint16_t link_speed;
|
||||
uint16_t support_speeds;
|
||||
uint16_t auto_link_speeds;
|
||||
uint16_t auto_link_speed;
|
||||
uint16_t force_link_speed;
|
||||
uint32_t preemphasis;
|
||||
|
||||
/* copy of requested setting */
|
||||
uint8_t autoneg;
|
||||
#define BNXT_AUTONEG_SPEED 1
|
||||
#define BNXT_AUTONEG_FLOW_CTRL 2
|
||||
uint8_t req_duplex;
|
||||
uint8_t req_flow_ctrl;
|
||||
uint16_t req_link_speed;
|
||||
};
|
||||
|
||||
enum bnxt_cp_type {
|
||||
BNXT_DEFAULT,
|
||||
BNXT_TX,
|
||||
BNXT_RX,
|
||||
BNXT_SHARED
|
||||
};
|
||||
|
||||
struct bnxt_cos_queue {
|
||||
uint8_t id;
|
||||
uint8_t profile;
|
||||
};
|
||||
|
||||
struct bnxt_func_info {
|
||||
uint32_t fw_fid;
|
||||
uint8_t mac_addr[ETHER_ADDR_LEN];
|
||||
uint16_t max_rsscos_ctxs;
|
||||
uint16_t max_cp_rings;
|
||||
uint16_t max_tx_rings;
|
||||
uint16_t max_rx_rings;
|
||||
uint16_t max_hw_ring_grps;
|
||||
uint16_t max_irqs;
|
||||
uint16_t max_l2_ctxs;
|
||||
uint16_t max_vnics;
|
||||
uint16_t max_stat_ctxs;
|
||||
};
|
||||
|
||||
struct bnxt_pf_info {
|
||||
#define BNXT_FIRST_PF_FID 1
|
||||
#define BNXT_FIRST_VF_FID 128
|
||||
uint8_t port_id;
|
||||
uint32_t first_vf_id;
|
||||
uint16_t active_vfs;
|
||||
uint16_t max_vfs;
|
||||
uint32_t max_encap_records;
|
||||
uint32_t max_decap_records;
|
||||
uint32_t max_tx_em_flows;
|
||||
uint32_t max_tx_wm_flows;
|
||||
uint32_t max_rx_em_flows;
|
||||
uint32_t max_rx_wm_flows;
|
||||
unsigned long *vf_event_bmap;
|
||||
uint16_t hwrm_cmd_req_pages;
|
||||
void *hwrm_cmd_req_addr[4];
|
||||
bus_addr_t hwrm_cmd_req_dma_addr[4];
|
||||
};
|
||||
|
||||
struct bnxt_vf_info {
|
||||
uint16_t fw_fid;
|
||||
uint8_t mac_addr[ETHER_ADDR_LEN];
|
||||
uint16_t max_rsscos_ctxs;
|
||||
uint16_t max_cp_rings;
|
||||
uint16_t max_tx_rings;
|
||||
uint16_t max_rx_rings;
|
||||
uint16_t max_hw_ring_grps;
|
||||
uint16_t max_l2_ctxs;
|
||||
uint16_t max_irqs;
|
||||
uint16_t max_vnics;
|
||||
uint16_t max_stat_ctxs;
|
||||
uint32_t vlan;
|
||||
#define BNXT_VF_QOS 0x1
|
||||
#define BNXT_VF_SPOOFCHK 0x2
|
||||
#define BNXT_VF_LINK_FORCED 0x4
|
||||
#define BNXT_VF_LINK_UP 0x8
|
||||
uint32_t flags;
|
||||
uint32_t func_flags; /* func cfg flags */
|
||||
uint32_t min_tx_rate;
|
||||
uint32_t max_tx_rate;
|
||||
void *hwrm_cmd_req_addr;
|
||||
bus_addr_t hwrm_cmd_req_dma_addr;
|
||||
};
|
||||
|
||||
#define BNXT_FLAG_VF (1<<1)
|
||||
|
||||
#define BNXT_PF(softc) (!((softc)->flags & BNXT_FLAG_VF))
|
||||
#define BNXT_VF(softc) ((softc)->flags & BNXT_FLAG_VF)
|
||||
|
||||
struct bnxt_vlan_tag {
|
||||
SLIST_ENTRY(bnxt_vlan_tag) next;
|
||||
uint16_t tpid;
|
||||
uint16_t tag;
|
||||
};
|
||||
|
||||
struct bnxt_vnic_info {
|
||||
uint16_t id;
|
||||
uint16_t def_ring_grp;
|
||||
uint16_t cos_rule;
|
||||
uint16_t lb_rule;
|
||||
uint16_t mru;
|
||||
|
||||
uint32_t rx_mask;
|
||||
bool vlan_only;
|
||||
struct iflib_dma_info mc_list;
|
||||
int mc_list_count;
|
||||
#define BNXT_MAX_MC_ADDRS 16
|
||||
|
||||
uint32_t flags;
|
||||
#define BNXT_VNIC_FLAG_DEFAULT 0x01
|
||||
#define BNXT_VNIC_FLAG_BD_STALL 0x02
|
||||
#define BNXT_VNIC_FLAG_VLAN_STRIP 0x04
|
||||
|
||||
uint64_t filter_id;
|
||||
uint32_t flow_id;
|
||||
|
||||
uint16_t rss_id;
|
||||
uint32_t rss_hash_type;
|
||||
uint8_t rss_hash_key[HW_HASH_KEY_SIZE];
|
||||
struct iflib_dma_info rss_hash_key_tbl;
|
||||
struct iflib_dma_info rss_grp_tbl;
|
||||
SLIST_HEAD(vlan_head, bnxt_vlan_tag) vlan_tags;
|
||||
struct iflib_dma_info vlan_tag_list;
|
||||
};
|
||||
|
||||
struct bnxt_grp_info {
|
||||
uint16_t stats_ctx;
|
||||
uint16_t grp_id;
|
||||
uint16_t rx_ring_id;
|
||||
uint16_t cp_ring_id;
|
||||
uint16_t ag_ring_id;
|
||||
};
|
||||
|
||||
struct bnxt_ring {
|
||||
uint64_t paddr;
|
||||
vm_offset_t doorbell;
|
||||
caddr_t vaddr;
|
||||
struct bnxt_softc *softc;
|
||||
uint32_t ring_size; /* Must be a power of two */
|
||||
uint16_t id; /* Logical ID */
|
||||
uint16_t phys_id;
|
||||
};
|
||||
|
||||
struct bnxt_cp_ring {
|
||||
struct bnxt_ring ring;
|
||||
struct if_irq irq;
|
||||
uint32_t cons;
|
||||
bool v_bit; /* Value of valid bit */
|
||||
struct ctx_hw_stats *stats;
|
||||
uint32_t stats_ctx_id;
|
||||
uint32_t last_idx; /* Used by RX rings only
|
||||
* set to the last read pidx
|
||||
*/
|
||||
};
|
||||
|
||||
struct bnxt_full_tpa_start {
|
||||
struct rx_tpa_start_cmpl low;
|
||||
struct rx_tpa_start_cmpl_hi high;
|
||||
};
|
||||
|
||||
/* All the version information for the part */
|
||||
#define BNXT_VERSTR_SIZE (3*3+2+1) /* ie: "255.255.255\0" */
|
||||
#define BNXT_NAME_SIZE 17
|
||||
struct bnxt_ver_info {
|
||||
uint8_t hwrm_if_major;
|
||||
uint8_t hwrm_if_minor;
|
||||
uint8_t hwrm_if_update;
|
||||
char hwrm_if_ver[BNXT_VERSTR_SIZE];
|
||||
char driver_hwrm_if_ver[BNXT_VERSTR_SIZE];
|
||||
char hwrm_fw_ver[BNXT_VERSTR_SIZE];
|
||||
char mgmt_fw_ver[BNXT_VERSTR_SIZE];
|
||||
char netctrl_fw_ver[BNXT_VERSTR_SIZE];
|
||||
char roce_fw_ver[BNXT_VERSTR_SIZE];
|
||||
char phy_ver[BNXT_VERSTR_SIZE];
|
||||
char pkg_ver[64];
|
||||
|
||||
char hwrm_fw_name[BNXT_NAME_SIZE];
|
||||
char mgmt_fw_name[BNXT_NAME_SIZE];
|
||||
char netctrl_fw_name[BNXT_NAME_SIZE];
|
||||
char roce_fw_name[BNXT_NAME_SIZE];
|
||||
char phy_vendor[BNXT_NAME_SIZE];
|
||||
char phy_partnumber[BNXT_NAME_SIZE];
|
||||
|
||||
uint16_t chip_num;
|
||||
uint8_t chip_rev;
|
||||
uint8_t chip_metal;
|
||||
uint8_t chip_bond_id;
|
||||
uint8_t chip_type;
|
||||
|
||||
uint8_t hwrm_min_major;
|
||||
uint8_t hwrm_min_minor;
|
||||
uint8_t hwrm_min_update;
|
||||
|
||||
struct sysctl_ctx_list ver_ctx;
|
||||
struct sysctl_oid *ver_oid;
|
||||
};
|
||||
|
||||
struct bnxt_nvram_info {
|
||||
uint16_t mfg_id;
|
||||
uint16_t device_id;
|
||||
uint32_t sector_size;
|
||||
uint32_t size;
|
||||
uint32_t reserved_size;
|
||||
uint32_t available_size;
|
||||
|
||||
struct sysctl_ctx_list nvm_ctx;
|
||||
struct sysctl_oid *nvm_oid;
|
||||
};
|
||||
|
||||
struct bnxt_softc {
|
||||
device_t dev;
|
||||
if_ctx_t ctx;
|
||||
if_softc_ctx_t scctx;
|
||||
if_shared_ctx_t sctx;
|
||||
struct ifmedia *media;
|
||||
|
||||
struct bnxt_bar_info hwrm_bar;
|
||||
struct bnxt_bar_info doorbell_bar;
|
||||
struct bnxt_link_info link_info;
|
||||
#define BNXT_FLAG_NPAR 1
|
||||
uint32_t flags;
|
||||
uint32_t total_msix;
|
||||
|
||||
struct bnxt_func_info func;
|
||||
struct bnxt_pf_info pf;
|
||||
struct bnxt_vf_info vf;
|
||||
|
||||
uint16_t hwrm_cmd_seq;
|
||||
uint32_t hwrm_cmd_timeo; /* milliseconds */
|
||||
struct iflib_dma_info hwrm_cmd_resp;
|
||||
/* Interrupt info for HWRM */
|
||||
struct if_irq irq;
|
||||
struct mtx hwrm_lock;
|
||||
uint16_t hwrm_max_req_len;
|
||||
|
||||
#define BNXT_MAX_QUEUE 8
|
||||
uint8_t max_tc;
|
||||
struct bnxt_cos_queue q_info[BNXT_MAX_QUEUE];
|
||||
|
||||
struct iflib_dma_info hw_rx_port_stats;
|
||||
struct iflib_dma_info hw_tx_port_stats;
|
||||
struct rx_port_stats *rx_port_stats;
|
||||
struct tx_port_stats *tx_port_stats;
|
||||
|
||||
int num_cp_rings;
|
||||
|
||||
struct bnxt_ring *tx_rings;
|
||||
struct bnxt_cp_ring *tx_cp_rings;
|
||||
struct iflib_dma_info tx_stats;
|
||||
int ntxqsets;
|
||||
|
||||
struct bnxt_vnic_info vnic_info;
|
||||
struct bnxt_ring *ag_rings;
|
||||
struct bnxt_ring *rx_rings;
|
||||
struct bnxt_cp_ring *rx_cp_rings;
|
||||
struct bnxt_grp_info *grp_info;
|
||||
struct iflib_dma_info rx_stats;
|
||||
int nrxqsets;
|
||||
|
||||
struct bnxt_cp_ring def_cp_ring;
|
||||
struct iflib_dma_info def_cp_ring_mem;
|
||||
struct grouptask def_cp_task;
|
||||
|
||||
struct sysctl_ctx_list hw_stats;
|
||||
struct sysctl_oid *hw_stats_oid;
|
||||
|
||||
struct bnxt_full_tpa_start *tpa_start;
|
||||
struct bnxt_ver_info *ver_info;
|
||||
struct bnxt_nvram_info *nvm_info;
|
||||
};
|
||||
|
||||
struct bnxt_filter_info {
|
||||
STAILQ_ENTRY(bnxt_filter_info) next;
|
||||
uint64_t fw_l2_filter_id;
|
||||
#define INVALID_MAC_INDEX ((uint16_t)-1)
|
||||
uint16_t mac_index;
|
||||
|
||||
/* Filter Characteristics */
|
||||
uint32_t flags;
|
||||
uint32_t enables;
|
||||
uint8_t l2_addr[ETHER_ADDR_LEN];
|
||||
uint8_t l2_addr_mask[ETHER_ADDR_LEN];
|
||||
uint16_t l2_ovlan;
|
||||
uint16_t l2_ovlan_mask;
|
||||
uint16_t l2_ivlan;
|
||||
uint16_t l2_ivlan_mask;
|
||||
uint8_t t_l2_addr[ETHER_ADDR_LEN];
|
||||
uint8_t t_l2_addr_mask[ETHER_ADDR_LEN];
|
||||
uint16_t t_l2_ovlan;
|
||||
uint16_t t_l2_ovlan_mask;
|
||||
uint16_t t_l2_ivlan;
|
||||
uint16_t t_l2_ivlan_mask;
|
||||
uint8_t tunnel_type;
|
||||
uint16_t mirror_vnic_id;
|
||||
uint32_t vni;
|
||||
uint8_t pri_hint;
|
||||
uint64_t l2_filter_id_hint;
|
||||
};
|
||||
|
||||
/* Function declarations */
|
||||
void bnxt_report_link(struct bnxt_softc *softc);
|
||||
bool bnxt_check_hwrm_version(struct bnxt_softc *softc);
|
||||
|
||||
#endif /* _BNXT_H */
|
||||
1485
sys/dev/bnxt/bnxt_hwrm.c
Normal file
1485
sys/dev/bnxt/bnxt_hwrm.c
Normal file
File diff suppressed because it is too large
Load diff
102
sys/dev/bnxt/bnxt_hwrm.h
Normal file
102
sys/dev/bnxt/bnxt_hwrm.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifndef _BNXT_HWRM_H
|
||||
#define _BNXT_HWRM_H
|
||||
|
||||
/* HWRM Function Prototypes */
|
||||
int bnxt_alloc_hwrm_dma_mem(struct bnxt_softc *softc);
|
||||
void bnxt_free_hwrm_dma_mem(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_ring_alloc(struct bnxt_softc *softc, uint8_t type,
|
||||
struct bnxt_ring *ring, uint16_t cmpl_ring_id, uint32_t stat_ctx_id,
|
||||
bool irq);
|
||||
int bnxt_hwrm_ver_get(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_func_drv_rgtr(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_func_drv_unrgtr(struct bnxt_softc *softc, bool shutdown);
|
||||
int bnxt_hwrm_func_qcaps(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_func_reset(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_set_link_setting(struct bnxt_softc *, bool set_pause,
|
||||
bool set_eee);
|
||||
int bnxt_hwrm_set_pause(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_vnic_ctx_alloc(struct bnxt_softc *softc, uint16_t *ctx_id);
|
||||
int bnxt_hwrm_vnic_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic);
|
||||
int bnxt_hwrm_stat_ctx_alloc(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr,
|
||||
uint64_t paddr);
|
||||
int bnxt_hwrm_ring_grp_alloc(struct bnxt_softc *softc,
|
||||
struct bnxt_grp_info *grp);
|
||||
int bnxt_hwrm_vnic_alloc(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic);
|
||||
int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *softc,
|
||||
struct bnxt_vnic_info *vnic);
|
||||
int bnxt_hwrm_set_filter(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic);
|
||||
int bnxt_hwrm_rss_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic,
|
||||
uint32_t hash_type);
|
||||
int bnxt_hwrm_func_cfg(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc,
|
||||
struct bnxt_vnic_info *vnic, uint32_t flags);
|
||||
int bnxt_hwrm_nvm_find_dir_entry(struct bnxt_softc *softc, uint16_t type,
|
||||
uint16_t *ordinal, uint16_t ext, uint16_t *index, bool use_index,
|
||||
uint8_t search_opt, uint32_t *data_length, uint32_t *item_length,
|
||||
uint32_t *fw_ver);
|
||||
int bnxt_hwrm_nvm_read(struct bnxt_softc *softc, uint16_t index,
|
||||
uint32_t offset, uint32_t length, struct iflib_dma_info *data);
|
||||
int bnxt_hwrm_nvm_modify(struct bnxt_softc *softc, uint16_t index,
|
||||
uint32_t offset, void *data, bool cpyin, uint32_t length);
|
||||
int bnxt_hwrm_fw_reset(struct bnxt_softc *softc, uint8_t processor,
|
||||
uint8_t *selfreset);
|
||||
int bnxt_hwrm_fw_qstatus(struct bnxt_softc *softc, uint8_t type,
|
||||
uint8_t *selfreset);
|
||||
int bnxt_hwrm_nvm_write(struct bnxt_softc *softc, void *data, bool cpyin,
|
||||
uint16_t type, uint16_t ordinal, uint16_t ext, uint16_t attr,
|
||||
uint16_t option, uint32_t data_length, bool keep, uint32_t *item_length,
|
||||
uint16_t *index);
|
||||
int bnxt_hwrm_nvm_erase_dir_entry(struct bnxt_softc *softc, uint16_t index);
|
||||
int bnxt_hwrm_nvm_get_dir_info(struct bnxt_softc *softc, uint32_t *entries,
|
||||
uint32_t *entry_length);
|
||||
int bnxt_hwrm_nvm_get_dir_entries(struct bnxt_softc *softc,
|
||||
uint32_t *entries, uint32_t *entry_length, struct iflib_dma_info *dma_data);
|
||||
int bnxt_hwrm_nvm_get_dev_info(struct bnxt_softc *softc, uint16_t *mfg_id,
|
||||
uint16_t *device_id, uint32_t *sector_size, uint32_t *nvram_size,
|
||||
uint32_t *reserved_size, uint32_t *available_size);
|
||||
int bnxt_hwrm_nvm_install_update(struct bnxt_softc *softc,
|
||||
uint32_t install_type, uint64_t *installed_items, uint8_t *result,
|
||||
uint8_t *problem_item, uint8_t *reset_required);
|
||||
int bnxt_hwrm_nvm_verify_update(struct bnxt_softc *softc, uint16_t type,
|
||||
uint16_t ordinal, uint16_t ext);
|
||||
int bnxt_hwrm_fw_get_time(struct bnxt_softc *softc, uint16_t *year,
|
||||
uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute,
|
||||
uint8_t *second, uint16_t *millisecond, uint16_t *zone);
|
||||
int bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year,
|
||||
uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
|
||||
uint16_t millisecond, uint16_t zone);
|
||||
int bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc);
|
||||
|
||||
#endif
|
||||
192
sys/dev/bnxt/bnxt_ioctl.h
Normal file
192
sys/dev/bnxt/bnxt_ioctl.h
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifndef _BNXT_IOCTL_H
|
||||
#define _BNXT_IOCTL_H
|
||||
|
||||
enum bnxt_ioctl_type {
|
||||
BNXT_HWRM_NVM_FIND_DIR_ENTRY,
|
||||
BNXT_HWRM_NVM_READ,
|
||||
BNXT_HWRM_FW_RESET,
|
||||
BNXT_HWRM_FW_QSTATUS,
|
||||
BNXT_HWRM_NVM_WRITE,
|
||||
BNXT_HWRM_NVM_ERASE_DIR_ENTRY,
|
||||
BNXT_HWRM_NVM_GET_DIR_INFO,
|
||||
BNXT_HWRM_NVM_GET_DIR_ENTRIES,
|
||||
BNXT_HWRM_NVM_MODIFY,
|
||||
BNXT_HWRM_NVM_VERIFY_UPDATE,
|
||||
BNXT_HWRM_NVM_INSTALL_UPDATE,
|
||||
BNXT_HWRM_FW_GET_TIME,
|
||||
BNXT_HWRM_FW_SET_TIME,
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_header {
|
||||
enum bnxt_ioctl_type type;
|
||||
int rc;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_find_dir_entry {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint32_t data_length;
|
||||
uint32_t fw_ver;
|
||||
uint32_t item_length;
|
||||
uint16_t ext;
|
||||
uint16_t index;
|
||||
uint16_t ordinal;
|
||||
uint16_t type;
|
||||
uint8_t search_opt;
|
||||
bool use_index;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_read {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint8_t *data;
|
||||
uint32_t length;
|
||||
uint32_t offset;
|
||||
uint16_t index;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_fw_reset {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint8_t processor;
|
||||
uint8_t selfreset;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_fw_qstatus {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint8_t processor;
|
||||
uint8_t selfreset;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_write {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint8_t *data;
|
||||
uint32_t data_length;
|
||||
uint32_t item_length;
|
||||
uint16_t attr;
|
||||
uint16_t ext;
|
||||
uint16_t index;
|
||||
uint16_t option;
|
||||
uint16_t ordinal;
|
||||
uint16_t type;
|
||||
bool keep;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_erase_dir_entry {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
enum bnxt_ioctl_type type;
|
||||
int rc;
|
||||
uint16_t index;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_get_dir_info {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint32_t entries;
|
||||
uint32_t entry_length;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_get_dir_entries {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint8_t *data;
|
||||
size_t max_size;
|
||||
uint32_t entries;
|
||||
uint32_t entry_length;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_install_update {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint64_t installed_items;
|
||||
uint32_t install_type;
|
||||
uint8_t problem_item;
|
||||
uint8_t reset_required;
|
||||
uint8_t result;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_verify_update {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint16_t ext;
|
||||
uint16_t ordinal;
|
||||
uint16_t type;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_nvm_modify {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint8_t *data;
|
||||
uint32_t length;
|
||||
uint32_t offset;
|
||||
uint16_t index;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_fw_get_time {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint16_t millisecond;
|
||||
uint16_t year;
|
||||
uint16_t zone;
|
||||
uint8_t day;
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t month;
|
||||
uint8_t second;
|
||||
};
|
||||
|
||||
struct bnxt_ioctl_hwrm_fw_set_time {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
uint16_t millisecond;
|
||||
uint16_t year;
|
||||
uint16_t zone;
|
||||
uint8_t day;
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t month;
|
||||
uint8_t second;
|
||||
};
|
||||
|
||||
/* IOCTL interface */
|
||||
struct bnxt_ioctl_data {
|
||||
union {
|
||||
struct bnxt_ioctl_header hdr;
|
||||
struct bnxt_ioctl_hwrm_nvm_find_dir_entry find;
|
||||
struct bnxt_ioctl_hwrm_nvm_read read;
|
||||
struct bnxt_ioctl_hwrm_fw_reset reset;
|
||||
struct bnxt_ioctl_hwrm_fw_qstatus status;
|
||||
struct bnxt_ioctl_hwrm_nvm_write write;
|
||||
struct bnxt_ioctl_hwrm_nvm_erase_dir_entry erase;
|
||||
struct bnxt_ioctl_hwrm_nvm_get_dir_info dir_info;
|
||||
struct bnxt_ioctl_hwrm_nvm_get_dir_entries dir_entries;
|
||||
struct bnxt_ioctl_hwrm_nvm_install_update install;
|
||||
struct bnxt_ioctl_hwrm_nvm_verify_update verify;
|
||||
struct bnxt_ioctl_hwrm_nvm_modify modify;
|
||||
struct bnxt_ioctl_hwrm_fw_get_time get_time;
|
||||
struct bnxt_ioctl_hwrm_fw_set_time set_time;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
618
sys/dev/bnxt/bnxt_sysctl.c
Normal file
618
sys/dev/bnxt/bnxt_sysctl.c
Normal file
|
|
@ -0,0 +1,618 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include "bnxt.h"
|
||||
#include "bnxt_hwrm.h"
|
||||
#include "bnxt_sysctl.h"
|
||||
|
||||
static int bnxt_vlan_only_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
/*
|
||||
* We want to create:
|
||||
* dev.bnxt.0.hwstats.txq0
|
||||
* dev.bnxt.0.hwstats.txq0.txmbufs
|
||||
* dev.bnxt.0.hwstats.rxq0
|
||||
* dev.bnxt.0.hwstats.txq0.rxmbufs
|
||||
* so the hwstats ctx list needs to be created in attach_post and populated
|
||||
* during init.
|
||||
*
|
||||
* Then, it needs to be cleaned up in stop.
|
||||
*/
|
||||
|
||||
int
|
||||
bnxt_init_sysctl_ctx(struct bnxt_softc *softc)
|
||||
{
|
||||
struct sysctl_ctx_list *ctx;
|
||||
|
||||
sysctl_ctx_init(&softc->hw_stats);
|
||||
ctx = device_get_sysctl_ctx(softc->dev);
|
||||
softc->hw_stats_oid = SYSCTL_ADD_NODE(ctx,
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO,
|
||||
"hwstats", CTLFLAG_RD, 0, "hardware statistics");
|
||||
if (!softc->hw_stats_oid) {
|
||||
sysctl_ctx_free(&softc->hw_stats);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
sysctl_ctx_init(&softc->ver_info->ver_ctx);
|
||||
ctx = device_get_sysctl_ctx(softc->dev);
|
||||
softc->ver_info->ver_oid = SYSCTL_ADD_NODE(ctx,
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO,
|
||||
"ver", CTLFLAG_RD, 0, "hardware/firmware version information");
|
||||
if (!softc->ver_info->ver_oid) {
|
||||
sysctl_ctx_free(&softc->ver_info->ver_ctx);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
sysctl_ctx_init(&softc->nvm_info->nvm_ctx);
|
||||
ctx = device_get_sysctl_ctx(softc->dev);
|
||||
softc->nvm_info->nvm_oid = SYSCTL_ADD_NODE(ctx,
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO,
|
||||
"nvram", CTLFLAG_RD, 0, "nvram information");
|
||||
if (!softc->nvm_info->nvm_oid) {
|
||||
sysctl_ctx_free(&softc->nvm_info->nvm_ctx);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_free_sysctl_ctx(struct bnxt_softc *softc)
|
||||
{
|
||||
int orc;
|
||||
int rc = 0;
|
||||
|
||||
if (softc->hw_stats_oid != NULL) {
|
||||
orc = sysctl_ctx_free(&softc->hw_stats);
|
||||
if (orc)
|
||||
rc = orc;
|
||||
else
|
||||
softc->hw_stats_oid = NULL;
|
||||
}
|
||||
if (softc->ver_info->ver_oid != NULL) {
|
||||
orc = sysctl_ctx_free(&softc->ver_info->ver_ctx);
|
||||
if (orc)
|
||||
rc = orc;
|
||||
else
|
||||
softc->ver_info->ver_oid = NULL;
|
||||
}
|
||||
if (softc->nvm_info->nvm_oid != NULL) {
|
||||
orc = sysctl_ctx_free(&softc->nvm_info->nvm_ctx);
|
||||
if (orc)
|
||||
rc = orc;
|
||||
else
|
||||
softc->nvm_info->nvm_oid = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_tx_sysctls(struct bnxt_softc *softc, int txr)
|
||||
{
|
||||
struct sysctl_oid *oid;
|
||||
struct ctx_hw_stats *tx_stats = (void *)softc->tx_stats.idi_vaddr;
|
||||
char name[32];
|
||||
char desc[64];
|
||||
|
||||
sprintf(name, "txq%d", txr);
|
||||
sprintf(desc, "transmit queue %d", txr);
|
||||
oid = SYSCTL_ADD_NODE(&softc->hw_stats,
|
||||
SYSCTL_CHILDREN(softc->hw_stats_oid), OID_AUTO, name, CTLFLAG_RD, 0,
|
||||
desc);
|
||||
if (!oid)
|
||||
return ENOMEM;
|
||||
|
||||
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"ucast_pkts", CTLFLAG_RD, &tx_stats[txr].tx_ucast_pkts,
|
||||
"unicast packets sent");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"mcast_pkts", CTLFLAG_RD, &tx_stats[txr].tx_mcast_pkts,
|
||||
"multicast packets sent");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"bcast_pkts", CTLFLAG_RD, &tx_stats[txr].tx_bcast_pkts,
|
||||
"broadcast packets sent");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"discard_pkts", CTLFLAG_RD,
|
||||
&tx_stats[txr].tx_discard_pkts, "discarded transmit packets");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"drop_pkts", CTLFLAG_RD, &tx_stats[txr].tx_drop_pkts,
|
||||
"dropped transmit packets");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"ucast_bytes", CTLFLAG_RD, &tx_stats[txr].tx_ucast_bytes,
|
||||
"unicast bytes sent");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"mcast_bytes", CTLFLAG_RD, &tx_stats[txr].tx_mcast_bytes,
|
||||
"multicast bytes sent");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"bcast_bytes", CTLFLAG_RD, &tx_stats[txr].tx_bcast_bytes,
|
||||
"broadcast bytes sent");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_rx_sysctls(struct bnxt_softc *softc, int rxr)
|
||||
{
|
||||
struct sysctl_oid *oid;
|
||||
struct ctx_hw_stats *rx_stats = (void *)softc->rx_stats.idi_vaddr;
|
||||
char name[32];
|
||||
char desc[64];
|
||||
|
||||
sprintf(name, "rxq%d", rxr);
|
||||
sprintf(desc, "receive queue %d", rxr);
|
||||
oid = SYSCTL_ADD_NODE(&softc->hw_stats,
|
||||
SYSCTL_CHILDREN(softc->hw_stats_oid), OID_AUTO, name, CTLFLAG_RD, 0,
|
||||
desc);
|
||||
if (!oid)
|
||||
return ENOMEM;
|
||||
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"ucast_pkts", CTLFLAG_RD, &rx_stats[rxr].rx_ucast_pkts,
|
||||
"unicast packets received");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"mcast_pkts", CTLFLAG_RD, &rx_stats[rxr].rx_mcast_pkts,
|
||||
"multicast packets received");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"bcast_pkts", CTLFLAG_RD, &rx_stats[rxr].rx_bcast_pkts,
|
||||
"broadcast packets received");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"discard_pkts", CTLFLAG_RD,
|
||||
&rx_stats[rxr].rx_discard_pkts, "discarded receive packets");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"drop_pkts", CTLFLAG_RD, &rx_stats[rxr].rx_drop_pkts,
|
||||
"dropped receive packets");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"ucast_bytes", CTLFLAG_RD, &rx_stats[rxr].rx_ucast_bytes,
|
||||
"unicast bytes received");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"mcast_bytes", CTLFLAG_RD, &rx_stats[rxr].rx_mcast_bytes,
|
||||
"multicast bytes received");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"bcast_bytes", CTLFLAG_RD, &rx_stats[rxr].rx_bcast_bytes,
|
||||
"broadcast bytes received");
|
||||
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"tpa_pkts", CTLFLAG_RD, &rx_stats[rxr].tpa_pkts,
|
||||
"TPA packets");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"tpa_bytes", CTLFLAG_RD, &rx_stats[rxr].tpa_bytes,
|
||||
"TPA bytes");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"tpa_events", CTLFLAG_RD, &rx_stats[rxr].tpa_events,
|
||||
"TPA events");
|
||||
SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"tpa_aborts", CTLFLAG_RD, &rx_stats[rxr].tpa_aborts,
|
||||
"TPA aborts");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *bnxt_chip_type[] = {
|
||||
"ASIC",
|
||||
"FPGA",
|
||||
"Palladium",
|
||||
"Unknown"
|
||||
};
|
||||
#define MAX_CHIP_TYPE 3
|
||||
|
||||
static int
|
||||
bnxt_package_ver_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
struct iflib_dma_info dma_data;
|
||||
char *pkglog = NULL;
|
||||
char *p;
|
||||
char *next;
|
||||
char unk[] = "<unknown>";
|
||||
char *buf = unk;
|
||||
int rc;
|
||||
int field;
|
||||
uint16_t ordinal = BNX_DIR_ORDINAL_FIRST;
|
||||
uint16_t index;
|
||||
uint32_t data_len;
|
||||
|
||||
rc = bnxt_hwrm_nvm_find_dir_entry(softc, BNX_DIR_TYPE_PKG_LOG,
|
||||
&ordinal, BNX_DIR_EXT_NONE, &index, false,
|
||||
HWRM_NVM_FIND_DIR_ENTRY_INPUT_OPT_ORDINAL_EQ,
|
||||
&data_len, NULL, NULL);
|
||||
dma_data.idi_vaddr = NULL;
|
||||
if (rc == 0 && data_len) {
|
||||
rc = iflib_dma_alloc(softc->ctx, data_len, &dma_data,
|
||||
BUS_DMA_NOWAIT);
|
||||
if (rc == 0) {
|
||||
rc = bnxt_hwrm_nvm_read(softc, index, 0, data_len,
|
||||
&dma_data);
|
||||
if (rc == 0) {
|
||||
pkglog = dma_data.idi_vaddr;
|
||||
/* NULL terminate (removes last \n) */
|
||||
pkglog[data_len-1] = 0;
|
||||
|
||||
/* Set p = start of last line */
|
||||
p = strrchr(pkglog, '\n');
|
||||
if (p == NULL)
|
||||
p = pkglog;
|
||||
|
||||
/* Now find the correct tab delimited field */
|
||||
for (field = 0, next = p,
|
||||
p = strsep(&next, "\t");
|
||||
field <
|
||||
BNX_PKG_LOG_FIELD_IDX_PKG_VERSION && p;
|
||||
p = strsep(&next, "\t")) {
|
||||
field++;
|
||||
}
|
||||
if (field == BNX_PKG_LOG_FIELD_IDX_PKG_VERSION)
|
||||
buf = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
dma_data.idi_vaddr = NULL;
|
||||
}
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, 0, req);
|
||||
if (dma_data.idi_vaddr)
|
||||
iflib_dma_free(&dma_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_min_ver_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
char buf[16];
|
||||
uint8_t newver[3];
|
||||
int rc;
|
||||
|
||||
sprintf(buf, "%hhu.%hhu.%hhu", softc->ver_info->hwrm_min_major,
|
||||
softc->ver_info->hwrm_min_minor, softc->ver_info->hwrm_min_update);
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (rc || req->newptr == NULL)
|
||||
return rc;
|
||||
if (sscanf(buf, "%hhu.%hhu.%hhu%*c", &newver[0], &newver[1],
|
||||
&newver[2]) != 3)
|
||||
return EINVAL;
|
||||
softc->ver_info->hwrm_min_major = newver[0];
|
||||
softc->ver_info->hwrm_min_minor = newver[1];
|
||||
softc->ver_info->hwrm_min_update = newver[2];
|
||||
bnxt_check_hwrm_version(softc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_ver_sysctls(struct bnxt_softc *softc)
|
||||
{
|
||||
struct bnxt_ver_info *vi = softc->ver_info;
|
||||
struct sysctl_oid *oid = vi->ver_oid;
|
||||
|
||||
if (!oid)
|
||||
return ENOMEM;
|
||||
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"hwrm_if", CTLFLAG_RD, vi->hwrm_if_ver, 0,
|
||||
"HWRM interface version");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"driver_hwrm_if", CTLFLAG_RD, vi->driver_hwrm_if_ver, 0,
|
||||
"HWRM firmware version");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"hwrm_fw", CTLFLAG_RD, vi->hwrm_fw_ver, 0,
|
||||
"HWRM firmware version");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"mgmt_fw", CTLFLAG_RD, vi->mgmt_fw_ver, 0,
|
||||
"management firmware version");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"netctrl_fw", CTLFLAG_RD, vi->netctrl_fw_ver, 0,
|
||||
"network control firmware version");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"roce_fw", CTLFLAG_RD, vi->roce_fw_ver, 0,
|
||||
"RoCE firmware version");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"phy", CTLFLAG_RD, vi->phy_ver, 0,
|
||||
"PHY version");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"hwrm_fw_name", CTLFLAG_RD, vi->hwrm_fw_name, 0,
|
||||
"HWRM firmware name");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"mgmt_fw_name", CTLFLAG_RD, vi->mgmt_fw_name, 0,
|
||||
"management firmware name");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"netctrl_fw_name", CTLFLAG_RD, vi->netctrl_fw_name, 0,
|
||||
"network control firmware name");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"roce_fw_name", CTLFLAG_RD, vi->roce_fw_name, 0,
|
||||
"RoCE firmware name");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"phy_vendor", CTLFLAG_RD, vi->phy_vendor, 0,
|
||||
"PHY vendor name");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"phy_partnumber", CTLFLAG_RD, vi->phy_partnumber, 0,
|
||||
"PHY vendor part number");
|
||||
SYSCTL_ADD_U16(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"chip_num", CTLFLAG_RD, &vi->chip_num, 0, "chip number");
|
||||
SYSCTL_ADD_U8(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"chip_rev", CTLFLAG_RD, &vi->chip_rev, 0, "chip revision");
|
||||
SYSCTL_ADD_U8(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"chip_metal", CTLFLAG_RD, &vi->chip_metal, 0, "chip metal number");
|
||||
SYSCTL_ADD_U8(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"chip_bond_id", CTLFLAG_RD, &vi->chip_bond_id, 0,
|
||||
"chip bond id");
|
||||
SYSCTL_ADD_STRING(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"chip_type", CTLFLAG_RD, vi->chip_type > MAX_CHIP_TYPE ?
|
||||
bnxt_chip_type[MAX_CHIP_TYPE] : bnxt_chip_type[vi->chip_type], 0,
|
||||
"RoCE firmware name");
|
||||
SYSCTL_ADD_PROC(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"package_ver", CTLTYPE_STRING|CTLFLAG_RD, softc, 0,
|
||||
bnxt_package_ver_sysctl, "A",
|
||||
"currently installed package version");
|
||||
SYSCTL_ADD_PROC(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"hwrm_min_ver", CTLTYPE_STRING|CTLFLAG_RWTUN, softc, 0,
|
||||
bnxt_hwrm_min_ver_sysctl, "A",
|
||||
"minimum hwrm API vesion to support");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_nvram_sysctls(struct bnxt_nvram_info *ni)
|
||||
{
|
||||
struct sysctl_oid *oid = ni->nvm_oid;
|
||||
|
||||
if (!oid)
|
||||
return ENOMEM;
|
||||
|
||||
SYSCTL_ADD_U16(&ni->nvm_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"mfg_id", CTLFLAG_RD, &ni->mfg_id, 0, "manufacturer id");
|
||||
SYSCTL_ADD_U16(&ni->nvm_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"device_id", CTLFLAG_RD, &ni->device_id, 0, "device id");
|
||||
SYSCTL_ADD_U32(&ni->nvm_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"sector_size", CTLFLAG_RD, &ni->sector_size, 0, "sector size");
|
||||
SYSCTL_ADD_U32(&ni->nvm_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"size", CTLFLAG_RD, &ni->size, 0, "nvram total size");
|
||||
SYSCTL_ADD_U32(&ni->nvm_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"reserved_size", CTLFLAG_RD, &ni->reserved_size, 0,
|
||||
"total reserved space");
|
||||
SYSCTL_ADD_U32(&ni->nvm_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"available_size", CTLFLAG_RD, &ni->available_size, 0,
|
||||
"total available space");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_rss_key_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
char buf[HW_HASH_KEY_SIZE*2+1] = {0};
|
||||
char *p;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
for (p = buf, i=0; i<HW_HASH_KEY_SIZE; i++)
|
||||
p += sprintf(p, "%02x", softc->vnic_info.rss_hash_key[i]);
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (rc || req->newptr == NULL)
|
||||
return rc;
|
||||
|
||||
if (strspn(buf, "0123456789abcdefABCDEF") != (HW_HASH_KEY_SIZE * 2))
|
||||
return EINVAL;
|
||||
|
||||
for (p = buf, i=0; i<HW_HASH_KEY_SIZE; i++) {
|
||||
if (sscanf(p, "%02hhx", &softc->vnic_info.rss_hash_key[i]) != 1)
|
||||
return EINVAL;
|
||||
p += 2;
|
||||
}
|
||||
|
||||
if (if_getdrvflags(iflib_get_ifp(softc->ctx)) & IFF_DRV_RUNNING)
|
||||
bnxt_hwrm_rss_cfg(softc, &softc->vnic_info,
|
||||
softc->vnic_info.rss_hash_type);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const char *bnxt_hash_types[] = {"ipv4", "tcp_ipv4", "udp_ipv4", "ipv6",
|
||||
"tcp_ipv6", "udp_ipv6", NULL};
|
||||
|
||||
static int bnxt_get_rss_type_str_bit(char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; bnxt_hash_types[i]; i++)
|
||||
if (strcmp(bnxt_hash_types[i], str) == 0)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_rss_type_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
char buf[256] = {0};
|
||||
char *p;
|
||||
char *next;
|
||||
int rc;
|
||||
int type;
|
||||
int bit;
|
||||
|
||||
for (type = softc->vnic_info.rss_hash_type; type;
|
||||
type &= ~(1<<bit)) {
|
||||
bit = ffs(type) - 1;
|
||||
if (bit >= sizeof(bnxt_hash_types) / sizeof(const char *))
|
||||
continue;
|
||||
if (type != softc->vnic_info.rss_hash_type)
|
||||
strcat(buf, ",");
|
||||
strcat(buf, bnxt_hash_types[bit]);
|
||||
}
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (rc || req->newptr == NULL)
|
||||
return rc;
|
||||
|
||||
for (type = 0, next = buf, p = strsep(&next, " ,"); p;
|
||||
p = strsep(&next, " ,")) {
|
||||
bit = bnxt_get_rss_type_str_bit(p);
|
||||
if (bit == -1)
|
||||
return EINVAL;
|
||||
type |= 1<<bit;
|
||||
}
|
||||
if (type != softc->vnic_info.rss_hash_type) {
|
||||
softc->vnic_info.rss_hash_type = type;
|
||||
if (if_getdrvflags(iflib_get_ifp(softc->ctx)) & IFF_DRV_RUNNING)
|
||||
bnxt_hwrm_rss_cfg(softc, &softc->vnic_info,
|
||||
softc->vnic_info.rss_hash_type);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_rx_stall_sysctl(SYSCTL_HANDLER_ARGS) {
|
||||
struct bnxt_softc *softc = arg1;
|
||||
int rc;
|
||||
int val;
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
val = (bool)(softc->vnic_info.flags & BNXT_VNIC_FLAG_BD_STALL);
|
||||
rc = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (rc || !req->newptr)
|
||||
return rc;
|
||||
|
||||
if (val)
|
||||
softc->vnic_info.flags |= BNXT_VNIC_FLAG_BD_STALL;
|
||||
else
|
||||
softc->vnic_info.flags &= ~BNXT_VNIC_FLAG_BD_STALL;
|
||||
|
||||
if (if_getdrvflags(iflib_get_ifp(softc->ctx)) & IFF_DRV_RUNNING)
|
||||
rc = bnxt_hwrm_vnic_cfg(softc, &softc->vnic_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_vlan_strip_sysctl(SYSCTL_HANDLER_ARGS) {
|
||||
struct bnxt_softc *softc = arg1;
|
||||
int rc;
|
||||
int val;
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
val = (bool)(softc->vnic_info.flags & BNXT_VNIC_FLAG_VLAN_STRIP);
|
||||
rc = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (rc || !req->newptr)
|
||||
return rc;
|
||||
|
||||
if (val)
|
||||
softc->vnic_info.flags |= BNXT_VNIC_FLAG_VLAN_STRIP;
|
||||
else
|
||||
softc->vnic_info.flags &= ~BNXT_VNIC_FLAG_VLAN_STRIP;
|
||||
|
||||
if (if_getdrvflags(iflib_get_ifp(softc->ctx)) & IFF_DRV_RUNNING)
|
||||
rc = bnxt_hwrm_vnic_cfg(softc, &softc->vnic_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_config_sysctls_pre(struct bnxt_softc *softc)
|
||||
{
|
||||
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(softc->dev);
|
||||
struct sysctl_oid_list *children;
|
||||
|
||||
children = SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev));;
|
||||
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rss_key",
|
||||
CTLTYPE_STRING|CTLFLAG_RWTUN, softc, 0, bnxt_rss_key_sysctl, "A",
|
||||
"RSS key");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rss_type",
|
||||
CTLTYPE_STRING|CTLFLAG_RWTUN, softc, 0, bnxt_rss_type_sysctl, "A",
|
||||
"RSS type bits");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_stall",
|
||||
CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_rx_stall_sysctl, "I",
|
||||
"buffer rx packets in hardware until the host posts new buffers");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "vlan_strip",
|
||||
CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_vlan_strip_sysctl, "I",
|
||||
"strip VLAN tag in the RX path");
|
||||
SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "if_name", CTLFLAG_RD,
|
||||
iflib_get_ifp(softc->ctx)->if_xname, 0, "interface name");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_vlan_only_sysctl(SYSCTL_HANDLER_ARGS) {
|
||||
struct bnxt_softc *softc = arg1;
|
||||
int rc;
|
||||
int val;
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
val = softc->vnic_info.vlan_only;
|
||||
rc = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (rc || !req->newptr)
|
||||
return rc;
|
||||
|
||||
if (val)
|
||||
val = 1;
|
||||
|
||||
if (val != softc->vnic_info.vlan_only) {
|
||||
softc->vnic_info.vlan_only = val;
|
||||
if (if_getdrvflags(iflib_get_ifp(softc->ctx)) & IFF_DRV_RUNNING)
|
||||
rc = bnxt_hwrm_cfa_l2_set_rx_mask(softc,
|
||||
&softc->vnic_info);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_config_sysctls_post(struct bnxt_softc *softc)
|
||||
{
|
||||
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(softc->dev);
|
||||
struct sysctl_oid_list *children;
|
||||
|
||||
children = SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev));;
|
||||
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "vlan_only",
|
||||
CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0, bnxt_vlan_only_sysctl, "I",
|
||||
"require vlan tag on received packets when vlan is enabled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
sys/dev/bnxt/bnxt_sysctl.h
Normal file
41
sys/dev/bnxt/bnxt_sysctl.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "bnxt.h"
|
||||
|
||||
int bnxt_init_sysctl_ctx(struct bnxt_softc *softc);
|
||||
int bnxt_free_sysctl_ctx(struct bnxt_softc *softc);
|
||||
int bnxt_create_tx_sysctls(struct bnxt_softc *softc, int txr);
|
||||
int bnxt_create_rx_sysctls(struct bnxt_softc *softc, int rxr);
|
||||
int bnxt_create_ver_sysctls(struct bnxt_softc *softc);
|
||||
int bnxt_create_nvram_sysctls(struct bnxt_nvram_info *ni);
|
||||
int bnxt_create_config_sysctls_pre(struct bnxt_softc *softc);
|
||||
int bnxt_create_config_sysctls_post(struct bnxt_softc *softc);
|
||||
641
sys/dev/bnxt/bnxt_txrx.c
Normal file
641
sys/dev/bnxt/bnxt_txrx.c
Normal file
|
|
@ -0,0 +1,641 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/endian.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/iflib.h>
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#include "opt_rss.h"
|
||||
|
||||
#include "bnxt.h"
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
|
||||
static int bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi);
|
||||
static void bnxt_isc_txd_flush(void *sc, uint16_t txqid, uint32_t pidx);
|
||||
static int bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, uint32_t cidx,
|
||||
bool clear);
|
||||
|
||||
static void bnxt_isc_rxd_refill(void *sc, uint16_t rxqid, uint8_t flid,
|
||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs, uint16_t count,
|
||||
uint16_t buf_size);
|
||||
static void bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid,
|
||||
uint32_t pidx);
|
||||
static int bnxt_isc_rxd_available(void *sc, uint16_t rxqid, uint32_t idx,
|
||||
int budget);
|
||||
static int bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri);
|
||||
|
||||
static int bnxt_intr(void *sc);
|
||||
|
||||
struct if_txrx bnxt_txrx = {
|
||||
bnxt_isc_txd_encap,
|
||||
bnxt_isc_txd_flush,
|
||||
bnxt_isc_txd_credits_update,
|
||||
bnxt_isc_rxd_available,
|
||||
bnxt_isc_rxd_pkt_get,
|
||||
bnxt_isc_rxd_refill,
|
||||
bnxt_isc_rxd_flush,
|
||||
bnxt_intr
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Dependent Packet Transmit and Receive Functions
|
||||
*/
|
||||
|
||||
static const uint16_t bnxt_tx_lhint[] = {
|
||||
TX_BD_SHORT_FLAGS_LHINT_LT512,
|
||||
TX_BD_SHORT_FLAGS_LHINT_LT1K,
|
||||
TX_BD_SHORT_FLAGS_LHINT_LT2K,
|
||||
TX_BD_SHORT_FLAGS_LHINT_LT2K,
|
||||
TX_BD_SHORT_FLAGS_LHINT_GTE2K,
|
||||
};
|
||||
|
||||
static int
|
||||
bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
struct bnxt_ring *txr = &softc->tx_rings[pi->ipi_qsidx];
|
||||
struct tx_bd_long *tbd;
|
||||
struct tx_bd_long_hi *tbdh;
|
||||
bool need_hi = false;
|
||||
uint16_t flags_type;
|
||||
uint16_t lflags;
|
||||
uint32_t cfa_meta;
|
||||
int seg = 0;
|
||||
|
||||
/* If we have offloads enabled, we need to use two BDs. */
|
||||
if ((pi->ipi_csum_flags & (CSUM_OFFLOAD | CSUM_TSO | CSUM_IP)) ||
|
||||
pi->ipi_mflags & M_VLANTAG)
|
||||
need_hi = true;
|
||||
|
||||
/* TODO: Devices before Cu+B1 need to not mix long and short BDs */
|
||||
need_hi = true;
|
||||
|
||||
pi->ipi_new_pidx = pi->ipi_pidx;
|
||||
tbd = &((struct tx_bd_long *)txr->vaddr)[pi->ipi_new_pidx];
|
||||
pi->ipi_ndescs = 0;
|
||||
/* No need to byte-swap the opaque value */
|
||||
tbd->opaque = ((pi->ipi_nsegs + need_hi) << 24) | pi->ipi_new_pidx;
|
||||
tbd->len = htole16(pi->ipi_segs[seg].ds_len);
|
||||
tbd->addr = htole64(pi->ipi_segs[seg++].ds_addr);
|
||||
flags_type = ((pi->ipi_nsegs + need_hi) <<
|
||||
TX_BD_SHORT_FLAGS_BD_CNT_SFT) & TX_BD_SHORT_FLAGS_BD_CNT_MASK;
|
||||
if (pi->ipi_len >= 2048)
|
||||
flags_type |= TX_BD_SHORT_FLAGS_LHINT_GTE2K;
|
||||
else
|
||||
flags_type |= bnxt_tx_lhint[pi->ipi_len >> 9];
|
||||
|
||||
if (need_hi) {
|
||||
flags_type |= TX_BD_LONG_TYPE_TX_BD_LONG;
|
||||
|
||||
pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx);
|
||||
tbdh = &((struct tx_bd_long_hi *)txr->vaddr)[pi->ipi_new_pidx];
|
||||
tbdh->mss = htole16(pi->ipi_tso_segsz);
|
||||
tbdh->hdr_size = htole16((pi->ipi_ehdrlen + pi->ipi_ip_hlen +
|
||||
pi->ipi_tcp_hlen) >> 1);
|
||||
tbdh->cfa_action = 0;
|
||||
lflags = 0;
|
||||
cfa_meta = 0;
|
||||
if (pi->ipi_mflags & M_VLANTAG) {
|
||||
/* TODO: Do we need to byte-swap the vtag here? */
|
||||
cfa_meta = TX_BD_LONG_CFA_META_KEY_VLAN_TAG |
|
||||
pi->ipi_vtag;
|
||||
cfa_meta |= TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100;
|
||||
}
|
||||
tbdh->cfa_meta = htole32(cfa_meta);
|
||||
if (pi->ipi_csum_flags & CSUM_TSO) {
|
||||
lflags |= TX_BD_LONG_LFLAGS_LSO |
|
||||
TX_BD_LONG_LFLAGS_T_IPID;
|
||||
}
|
||||
else if(pi->ipi_csum_flags & CSUM_OFFLOAD) {
|
||||
lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM |
|
||||
TX_BD_LONG_LFLAGS_IP_CHKSUM;
|
||||
}
|
||||
else if(pi->ipi_csum_flags & CSUM_IP) {
|
||||
lflags |= TX_BD_LONG_LFLAGS_IP_CHKSUM;
|
||||
}
|
||||
tbdh->lflags = htole16(lflags);
|
||||
}
|
||||
else {
|
||||
flags_type |= TX_BD_SHORT_TYPE_TX_BD_SHORT;
|
||||
}
|
||||
|
||||
for (; seg < pi->ipi_nsegs; seg++) {
|
||||
tbd->flags_type = htole16(flags_type);
|
||||
pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx);
|
||||
tbd = &((struct tx_bd_long *)txr->vaddr)[pi->ipi_new_pidx];
|
||||
tbd->len = htole16(pi->ipi_segs[seg].ds_len);
|
||||
tbd->addr = htole64(pi->ipi_segs[seg].ds_addr);
|
||||
flags_type = TX_BD_SHORT_TYPE_TX_BD_SHORT;
|
||||
}
|
||||
flags_type |= TX_BD_SHORT_FLAGS_PACKET_END;
|
||||
tbd->flags_type = htole16(flags_type);
|
||||
pi->ipi_new_pidx = RING_NEXT(txr, pi->ipi_new_pidx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bnxt_isc_txd_flush(void *sc, uint16_t txqid, uint32_t pidx)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
struct bnxt_ring *tx_ring = &softc->tx_rings[txqid];
|
||||
|
||||
/* pidx is what we last set ipi_new_pidx to */
|
||||
BNXT_TX_DB(tx_ring, pidx);
|
||||
/* TODO: Cumulus+ doesn't need the double doorbell */
|
||||
BNXT_TX_DB(tx_ring, pidx);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, uint32_t idx, bool clear)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
struct bnxt_cp_ring *cpr = &softc->tx_cp_rings[txqid];
|
||||
struct tx_cmpl *cmpl = (struct tx_cmpl *)cpr->ring.vaddr;
|
||||
int avail = 0;
|
||||
uint32_t cons = cpr->cons;
|
||||
bool v_bit = cpr->v_bit;
|
||||
bool last_v_bit;
|
||||
uint32_t last_cons;
|
||||
uint16_t type;
|
||||
uint16_t err;
|
||||
|
||||
for (;;) {
|
||||
last_cons = cons;
|
||||
last_v_bit = v_bit;
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
|
||||
if (!CMP_VALID(&cmpl[cons], v_bit))
|
||||
goto done;
|
||||
|
||||
type = cmpl[cons].flags_type & TX_CMPL_TYPE_MASK;
|
||||
switch (type) {
|
||||
case TX_CMPL_TYPE_TX_L2:
|
||||
err = (le16toh(cmpl[cons].errors_v) &
|
||||
TX_CMPL_ERRORS_BUFFER_ERROR_MASK) >>
|
||||
TX_CMPL_ERRORS_BUFFER_ERROR_SFT;
|
||||
if (err)
|
||||
device_printf(softc->dev,
|
||||
"TX completion error %u\n", err);
|
||||
/* No need to byte-swap the opaque value */
|
||||
avail += cmpl[cons].opaque >> 24;
|
||||
/*
|
||||
* If we're not clearing, iflib only cares if there's
|
||||
* at least one buffer. Don't scan the whole ring in
|
||||
* this case.
|
||||
*/
|
||||
if (!clear)
|
||||
goto done;
|
||||
break;
|
||||
default:
|
||||
if (type & 1) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
if (!CMP_VALID(&cmpl[cons], v_bit))
|
||||
goto done;
|
||||
}
|
||||
device_printf(softc->dev,
|
||||
"Unhandled TX completion type %u\n", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
if (clear && avail) {
|
||||
cpr->cons = last_cons;
|
||||
cpr->v_bit = last_v_bit;
|
||||
BNXT_CP_IDX_DISABLE_DB(&cpr->ring, cpr->cons);
|
||||
}
|
||||
|
||||
return avail;
|
||||
}
|
||||
|
||||
static void
|
||||
bnxt_isc_rxd_refill(void *sc, uint16_t rxqid, uint8_t flid,
|
||||
uint32_t pidx, uint64_t *paddrs,
|
||||
caddr_t *vaddrs, uint16_t count, uint16_t len)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
struct bnxt_ring *rx_ring;
|
||||
struct rx_prod_pkt_bd *rxbd;
|
||||
uint16_t type;
|
||||
uint16_t i;
|
||||
|
||||
if (flid == 0) {
|
||||
rx_ring = &softc->rx_rings[rxqid];
|
||||
type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT;
|
||||
}
|
||||
else {
|
||||
rx_ring = &softc->ag_rings[rxqid];
|
||||
type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG;
|
||||
}
|
||||
rxbd = (void *)rx_ring->vaddr;
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
rxbd[pidx].flags_type = htole16(type);
|
||||
rxbd[pidx].len = htole16(len);
|
||||
/* No need to byte-swap the opaque value */
|
||||
rxbd[pidx].opaque = ((rxqid & 0xff) << 24) | (flid << 16)
|
||||
| pidx;
|
||||
rxbd[pidx].addr = htole64(paddrs[i]);
|
||||
if (++pidx == rx_ring->ring_size)
|
||||
pidx = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t flid,
|
||||
uint32_t pidx)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
struct bnxt_ring *rx_ring;
|
||||
|
||||
if (flid == 0)
|
||||
rx_ring = &softc->rx_rings[rxqid];
|
||||
else
|
||||
rx_ring = &softc->ag_rings[rxqid];
|
||||
|
||||
/*
|
||||
* We *must* update the completion ring before updating the RX ring
|
||||
* or we will overrun the completion ring and the device will wedge for
|
||||
* RX.
|
||||
*/
|
||||
if (softc->rx_cp_rings[rxqid].cons != UINT32_MAX)
|
||||
BNXT_CP_IDX_DISABLE_DB(&softc->rx_cp_rings[rxqid].ring,
|
||||
softc->rx_cp_rings[rxqid].cons);
|
||||
/* We're given the last filled RX buffer here, not the next empty one */
|
||||
BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx));
|
||||
/* TODO: Cumulus+ doesn't need the double doorbell */
|
||||
BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx));
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_isc_rxd_available(void *sc, uint16_t rxqid, uint32_t idx, int budget)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[rxqid];
|
||||
struct rx_pkt_cmpl *rcp;
|
||||
struct rx_tpa_start_cmpl *rtpa;
|
||||
struct rx_tpa_end_cmpl *rtpae;
|
||||
struct cmpl_base *cmp = (struct cmpl_base *)cpr->ring.vaddr;
|
||||
int avail = 0;
|
||||
uint32_t cons = cpr->cons;
|
||||
bool v_bit = cpr->v_bit;
|
||||
uint8_t ags;
|
||||
int i;
|
||||
uint16_t type;
|
||||
uint8_t agg_id;
|
||||
|
||||
for (;;) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
|
||||
if (!CMP_VALID(&cmp[cons], v_bit))
|
||||
goto cmpl_invalid;
|
||||
|
||||
type = le16toh(cmp[cons].type) & CMPL_BASE_TYPE_MASK;
|
||||
switch (type) {
|
||||
case CMPL_BASE_TYPE_RX_L2:
|
||||
rcp = (void *)&cmp[cons];
|
||||
ags = (rcp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) >>
|
||||
RX_PKT_CMPL_AGG_BUFS_SFT;
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
|
||||
if (!CMP_VALID(&cmp[cons], v_bit))
|
||||
goto cmpl_invalid;
|
||||
|
||||
/* Now account for all the AG completions */
|
||||
for (i=0; i<ags; i++) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
if (!CMP_VALID(&cmp[cons], v_bit))
|
||||
goto cmpl_invalid;
|
||||
}
|
||||
avail++;
|
||||
break;
|
||||
case CMPL_BASE_TYPE_RX_TPA_END:
|
||||
rtpae = (void *)&cmp[cons];
|
||||
ags = (rtpae->agg_bufs_v1 &
|
||||
RX_TPA_END_CMPL_AGG_BUFS_MASK) >>
|
||||
RX_TPA_END_CMPL_AGG_BUFS_SFT;
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
|
||||
if (!CMP_VALID(&cmp[cons], v_bit))
|
||||
goto cmpl_invalid;
|
||||
/* Now account for all the AG completions */
|
||||
for (i=0; i<ags; i++) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
if (!CMP_VALID(&cmp[cons], v_bit))
|
||||
goto cmpl_invalid;
|
||||
}
|
||||
avail++;
|
||||
break;
|
||||
case CMPL_BASE_TYPE_RX_TPA_START:
|
||||
rtpa = (void *)&cmp[cons];
|
||||
agg_id = (rtpa->agg_id &
|
||||
RX_TPA_START_CMPL_AGG_ID_MASK) >>
|
||||
RX_TPA_START_CMPL_AGG_ID_SFT;
|
||||
softc->tpa_start[agg_id].low = *rtpa;
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
|
||||
if (!CMP_VALID(&cmp[cons], v_bit))
|
||||
goto cmpl_invalid;
|
||||
softc->tpa_start[agg_id].high =
|
||||
((struct rx_tpa_start_cmpl_hi *)cmp)[cons];
|
||||
break;
|
||||
case CMPL_BASE_TYPE_RX_AGG:
|
||||
break;
|
||||
default:
|
||||
device_printf(softc->dev,
|
||||
"Unhandled completion type %d on RXQ %d\n",
|
||||
type, rxqid);
|
||||
|
||||
/* Odd completion types use two completions */
|
||||
if (type & 1) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
|
||||
CMPL_PREFETCH_NEXT(cpr, cons);
|
||||
|
||||
if (!CMP_VALID(&cmp[cons], v_bit))
|
||||
goto cmpl_invalid;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (avail > budget)
|
||||
break;
|
||||
}
|
||||
cmpl_invalid:
|
||||
|
||||
return avail;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_pkt_get_l2(struct bnxt_softc *softc, if_rxd_info_t ri,
|
||||
struct bnxt_cp_ring *cpr, uint16_t flags_type)
|
||||
{
|
||||
struct rx_pkt_cmpl *rcp;
|
||||
struct rx_pkt_cmpl_hi *rcph;
|
||||
struct rx_abuf_cmpl *acp;
|
||||
uint32_t flags2;
|
||||
uint32_t errors;
|
||||
uint8_t ags;
|
||||
int i;
|
||||
|
||||
rcp = &((struct rx_pkt_cmpl *)cpr->ring.vaddr)[cpr->cons];
|
||||
|
||||
/* Extract from the first 16-byte BD */
|
||||
if (flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) {
|
||||
ri->iri_flowid = le32toh(rcp->rss_hash);
|
||||
/*
|
||||
* TODO: Extract something useful from rcp->rss_hash_type
|
||||
* (undocumented)
|
||||
* May be documented in the "LSI ES"
|
||||
* also check the firmware code.
|
||||
*/
|
||||
ri->iri_rsstype = M_HASHTYPE_OPAQUE;
|
||||
}
|
||||
else {
|
||||
ri->iri_rsstype = M_HASHTYPE_NONE;
|
||||
}
|
||||
ags = (rcp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) >>
|
||||
RX_PKT_CMPL_AGG_BUFS_SFT;
|
||||
ri->iri_nfrags = ags + 1;
|
||||
/* No need to byte-swap the opaque value */
|
||||
ri->iri_frags[0].irf_flid = (rcp->opaque >> 16) & 0xff;
|
||||
ri->iri_frags[0].irf_idx = rcp->opaque & 0xffff;
|
||||
ri->iri_frags[0].irf_len = le16toh(rcp->len);
|
||||
ri->iri_len = le16toh(rcp->len);
|
||||
|
||||
/* Now the second 16-byte BD */
|
||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
|
||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
|
||||
rcph = &((struct rx_pkt_cmpl_hi *)cpr->ring.vaddr)[cpr->cons];
|
||||
|
||||
flags2 = le32toh(rcph->flags2);
|
||||
errors = le16toh(rcph->errors_v2);
|
||||
if ((flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_MASK) ==
|
||||
RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
|
||||
ri->iri_flags |= M_VLANTAG;
|
||||
/* TODO: Should this be the entire 16-bits? */
|
||||
ri->iri_vtag = le32toh(rcph->metadata) &
|
||||
(RX_PKT_CMPL_METADATA_VID_MASK | RX_PKT_CMPL_METADATA_DE |
|
||||
RX_PKT_CMPL_METADATA_PRI_MASK);
|
||||
}
|
||||
if (flags2 & RX_PKT_CMPL_FLAGS2_IP_CS_CALC) {
|
||||
ri->iri_csum_flags |= CSUM_IP_CHECKED;
|
||||
if (!(errors & RX_PKT_CMPL_ERRORS_IP_CS_ERROR))
|
||||
ri->iri_csum_flags |= CSUM_IP_VALID;
|
||||
}
|
||||
if (flags2 & RX_PKT_CMPL_FLAGS2_L4_CS_CALC) {
|
||||
ri->iri_csum_flags |= CSUM_L4_CALC;
|
||||
if (!(errors & RX_PKT_CMPL_ERRORS_L4_CS_ERROR)) {
|
||||
ri->iri_csum_flags |= CSUM_L4_VALID;
|
||||
ri->iri_csum_data = 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* And finally the ag ring stuff. */
|
||||
for (i=1; i < ri->iri_nfrags; i++) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
|
||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
|
||||
acp = &((struct rx_abuf_cmpl *)cpr->ring.vaddr)[cpr->cons];
|
||||
|
||||
/* No need to byte-swap the opaque value */
|
||||
ri->iri_frags[i].irf_flid = (acp->opaque >> 16 & 0xff);
|
||||
ri->iri_frags[i].irf_idx = acp->opaque & 0xffff;
|
||||
ri->iri_frags[i].irf_len = le16toh(acp->len);
|
||||
ri->iri_len += le16toh(acp->len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_pkt_get_tpa(struct bnxt_softc *softc, if_rxd_info_t ri,
|
||||
struct bnxt_cp_ring *cpr, uint16_t flags_type)
|
||||
{
|
||||
struct rx_tpa_end_cmpl *agend =
|
||||
&((struct rx_tpa_end_cmpl *)cpr->ring.vaddr)[cpr->cons];
|
||||
struct rx_tpa_end_cmpl_hi *agendh;
|
||||
struct rx_abuf_cmpl *acp;
|
||||
struct bnxt_full_tpa_start *tpas;
|
||||
uint32_t flags2;
|
||||
uint8_t ags;
|
||||
uint8_t agg_id;
|
||||
int i;
|
||||
|
||||
/* Get the agg_id */
|
||||
agg_id = (agend->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK) >>
|
||||
RX_TPA_END_CMPL_AGG_ID_SFT;
|
||||
tpas = &softc->tpa_start[agg_id];
|
||||
|
||||
/* Extract from the first 16-byte BD */
|
||||
if (le16toh(tpas->low.flags_type) & RX_TPA_START_CMPL_FLAGS_RSS_VALID) {
|
||||
ri->iri_flowid = le32toh(tpas->low.rss_hash);
|
||||
/*
|
||||
* TODO: Extract something useful from tpas->low.rss_hash_type
|
||||
* (undocumented)
|
||||
* May be documented in the "LSI ES"
|
||||
* also check the firmware code.
|
||||
*/
|
||||
ri->iri_rsstype = M_HASHTYPE_OPAQUE;
|
||||
}
|
||||
else {
|
||||
ri->iri_rsstype = M_HASHTYPE_NONE;
|
||||
}
|
||||
ags = (agend->agg_bufs_v1 & RX_TPA_END_CMPL_AGG_BUFS_MASK) >>
|
||||
RX_TPA_END_CMPL_AGG_BUFS_SFT;
|
||||
ri->iri_nfrags = ags + 1;
|
||||
/* No need to byte-swap the opaque value */
|
||||
ri->iri_frags[0].irf_flid = (tpas->low.opaque >> 16) & 0xff;
|
||||
ri->iri_frags[0].irf_idx = tpas->low.opaque & 0xffff;
|
||||
ri->iri_frags[0].irf_len = le16toh(tpas->low.len);
|
||||
ri->iri_len = le16toh(tpas->low.len);
|
||||
|
||||
/* Now the second 16-byte BD */
|
||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
|
||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
|
||||
agendh = &((struct rx_tpa_end_cmpl_hi *)cpr->ring.vaddr)[cpr->cons];
|
||||
|
||||
flags2 = le32toh(tpas->high.flags2);
|
||||
if ((flags2 & RX_TPA_START_CMPL_FLAGS2_META_FORMAT_MASK) ==
|
||||
RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN) {
|
||||
ri->iri_flags |= M_VLANTAG;
|
||||
/* TODO: Should this be the entire 16-bits? */
|
||||
ri->iri_vtag = le32toh(tpas->high.metadata) &
|
||||
(RX_TPA_START_CMPL_METADATA_VID_MASK |
|
||||
RX_TPA_START_CMPL_METADATA_DE |
|
||||
RX_TPA_START_CMPL_METADATA_PRI_MASK);
|
||||
}
|
||||
if (flags2 & RX_TPA_START_CMPL_FLAGS2_IP_CS_CALC) {
|
||||
ri->iri_csum_flags |= CSUM_IP_CHECKED;
|
||||
ri->iri_csum_flags |= CSUM_IP_VALID;
|
||||
}
|
||||
if (flags2 & RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC) {
|
||||
ri->iri_csum_flags |= CSUM_L4_CALC;
|
||||
ri->iri_csum_flags |= CSUM_L4_VALID;
|
||||
ri->iri_csum_data = 0xffff;
|
||||
}
|
||||
|
||||
/* Now the ag ring stuff. */
|
||||
for (i=1; i < ri->iri_nfrags; i++) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
|
||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
|
||||
acp = &((struct rx_abuf_cmpl *)cpr->ring.vaddr)[cpr->cons];
|
||||
|
||||
/* No need to byte-swap the opaque value */
|
||||
ri->iri_frags[i].irf_flid = (acp->opaque >> 16) & 0xff;
|
||||
ri->iri_frags[i].irf_idx = acp->opaque & 0xffff;
|
||||
ri->iri_frags[i].irf_len = le16toh(acp->len);
|
||||
ri->iri_len += le16toh(acp->len);
|
||||
}
|
||||
|
||||
/* And finally, the empty BD at the end... */
|
||||
ri->iri_nfrags++;
|
||||
/* No need to byte-swap the opaque value */
|
||||
ri->iri_frags[i].irf_flid = (agend->opaque >> 16) % 0xff;
|
||||
ri->iri_frags[i].irf_idx = agend->opaque & 0xffff;
|
||||
ri->iri_frags[i].irf_len = le16toh(agend->len);
|
||||
ri->iri_len += le16toh(agend->len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we return anything but zero, iflib will assert... */
|
||||
static int
|
||||
bnxt_isc_rxd_pkt_get(void *sc, if_rxd_info_t ri)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
struct bnxt_cp_ring *cpr = &softc->rx_cp_rings[ri->iri_qsidx];
|
||||
struct cmpl_base *cmp;
|
||||
uint16_t flags_type;
|
||||
uint16_t type;
|
||||
|
||||
for (;;) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
|
||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
|
||||
CMPL_PREFETCH_NEXT(cpr, cpr->cons);
|
||||
cmp = &((struct cmpl_base *)cpr->ring.vaddr)[cpr->cons];
|
||||
|
||||
flags_type = le16toh(cmp->type);
|
||||
type = flags_type & CMPL_BASE_TYPE_MASK;
|
||||
|
||||
switch (type) {
|
||||
case CMPL_BASE_TYPE_RX_L2:
|
||||
return bnxt_pkt_get_l2(softc, ri, cpr, flags_type);
|
||||
case CMPL_BASE_TYPE_RX_TPA_END:
|
||||
return bnxt_pkt_get_tpa(softc, ri, cpr, flags_type);
|
||||
case CMPL_BASE_TYPE_RX_TPA_START:
|
||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons, cpr->v_bit);
|
||||
ri->iri_cidx = RING_NEXT(&cpr->ring, ri->iri_cidx);
|
||||
CMPL_PREFETCH_NEXT(cpr, cpr->cons);
|
||||
break;
|
||||
default:
|
||||
device_printf(softc->dev,
|
||||
"Unhandled completion type %d on RXQ %d get\n",
|
||||
type, ri->iri_qsidx);
|
||||
if (type & 1) {
|
||||
NEXT_CP_CONS_V(&cpr->ring, cpr->cons,
|
||||
cpr->v_bit);
|
||||
ri->iri_cidx = RING_NEXT(&cpr->ring,
|
||||
ri->iri_cidx);
|
||||
CMPL_PREFETCH_NEXT(cpr, cpr->cons);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_intr(void *sc)
|
||||
{
|
||||
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
|
||||
|
||||
device_printf(softc->dev, "STUB: %s @ %s:%d\n", __func__, __FILE__, __LINE__);
|
||||
return ENOSYS;
|
||||
}
|
||||
356
sys/dev/bnxt/convert_hsi.pl
Executable file
356
sys/dev/bnxt/convert_hsi.pl
Executable file
|
|
@ -0,0 +1,356 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
# This script cleans up the "official" Broadcom hsi_struct_defs.h file as distributed
|
||||
# to something somewhat more programmer friendly.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
my $do_decode = 0;
|
||||
|
||||
if (! -f $ARGV[0]) {
|
||||
print "Input file not specified (should be path to hsi_struct_defs.h)\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if (!open(IN, "<", $ARGV[0])) {
|
||||
print "Failure to open input file\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if (!open(OUT, ">", "hsi_struct_def.h")) {
|
||||
print "Failure to open output file\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
$/=undef;
|
||||
my $header = <IN>;
|
||||
close IN;
|
||||
|
||||
print OUT <<END_OF_NOTICE;
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("\$FreeBSD\$");
|
||||
|
||||
END_OF_NOTICE
|
||||
|
||||
# Convert line endings
|
||||
$header =~ s/\r\n/\n/gs;
|
||||
|
||||
# Convert arrays of two u32_t to a single uint64_t
|
||||
$header =~ s/\bu32_t(\s+[a-zA-Z0-9_]+)\[2\]/uint64_t$1/gs;
|
||||
|
||||
# Convert uint32_t *_lo/uint32_t *_hi to a single uint64_t
|
||||
$header =~ s/\bu32_t(\s+[a-zA-Z0-9_]+)_lo;\s*\r?\n\s*u32_t(\s+[a-zA-Z0-9_]+)_hi/uint64_t$1/gs;
|
||||
|
||||
# Convert types
|
||||
$header =~ s/\bu([0-9]+)_t\b/uint$1_t/gs;
|
||||
|
||||
# Convert literals
|
||||
$header =~ s/\b((?:0x)?[0-9a-f]+)UL/UINT32_C($1)/gs;
|
||||
|
||||
# Strip comments
|
||||
#$header =~ s/^(\s*[^\/\s][^\/]+?)\s*\/\*.*?\*\/\s*?$/$1/gm;
|
||||
#$header =~ s/[ \t]*\/\*.*?\*\/\s*?\n?//gs;
|
||||
|
||||
# Pack structs
|
||||
#$header =~ s/}(\s+)([^\s]+_t[,;])/} __attribute__((packed))$1$2/gs;
|
||||
|
||||
# Normalize indent
|
||||
$header =~ s/( ) +(#define)/$1$2/gs;
|
||||
$header =~ s/^(}[^\n]*;)\n([^\n])/$1\n\n$2/gsm;
|
||||
$header =~ s/([^\n])\n(typedef)/$1\n\n$2/gs;
|
||||
$header =~ s/ /\t/g;
|
||||
$header =~ s/ /\t/g;
|
||||
$header =~ s/([^\s]\t+) +/$1/g;
|
||||
|
||||
# Remove typedefs and pack structs
|
||||
$header =~ s/^typedef struct (.*?)\n{\n(.*?)}[^\n]*;/struct $1 {\n$2} __attribute__((packed));/gsm;
|
||||
|
||||
print OUT $header;
|
||||
close OUT;
|
||||
|
||||
if ($do_decode) {
|
||||
if(!open(OUT, ">", "hsi_struct_decode.c")) {
|
||||
print "Failure to open decoder output file\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print OUT <<END_OF_NOTICE;
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) 2016 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("\$FreeBSD\$");
|
||||
|
||||
END_OF_NOTICE
|
||||
|
||||
if(!open(HDR, ">", "hsi_struct_decode.h")) {
|
||||
print "Failure to open decoder output header file\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print HDR <<END_OF_NOTICE;
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2014-2015 Broadcom 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 Broadcom 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.
|
||||
*/
|
||||
|
||||
END_OF_NOTICE
|
||||
|
||||
print OUT "#ifdef HSI_DEBUG\n#include <inttypes.h>\n#include <rte_common.h>\n#include <rte_log.h>\n#include \"hsi_struct_def_dpdk.h\"\n#include \"hsi_struct_decode.h\"\n#include \"hsi_struct_decode.h\"\n\n";
|
||||
print HDR "#ifdef HSI_DEBUG\n#include \"hsi_struct_def_dpdk.h\"\n\n";
|
||||
|
||||
my $hdr_defs = '';
|
||||
|
||||
sub print_single_val
|
||||
{
|
||||
my $field=shift;
|
||||
my $type=shift;
|
||||
my $max_field_len=shift;
|
||||
my $name = shift;
|
||||
my $macroshash = shift;
|
||||
my %macros = %$macroshash;
|
||||
$macrosref = shift;
|
||||
my @macros = @$macrosref;
|
||||
$macrosref = shift;
|
||||
my @fields = @$macrosref;
|
||||
|
||||
if ($type eq 'uint32_t') {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s = 0x%%08\"PRIX32\"\\n\", data->$field);\n",$max_field_len,$field;
|
||||
}
|
||||
elsif ($type eq 'uint16_t') {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s = 0x%%04\"PRIX16\"\\n\", data->$field);\n",$max_field_len,$field;
|
||||
}
|
||||
elsif ($type eq 'uint8_t') {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s = 0x%%02\"PRIX8\"\\n\", data->$field);\n",$max_field_len,$field;
|
||||
}
|
||||
elsif ($type eq 'uint64_t') {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s = 0x%%016\"PRIX64\"\\n\", data->$field);\n",$max_field_len,$field;
|
||||
}
|
||||
elsif ($type eq 'char') {
|
||||
if ($field =~ s/\[([0-9]+)\]//) {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s = \\\"%%.$1s\\\"\\n\", data->$field);\n",$max_field_len,$field;
|
||||
}
|
||||
else {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s = 0x%%02\"PRIX8\"\\n\", data->$field);\n",$max_field_len,$field;
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "Unhandled type: '$type'\n";
|
||||
}
|
||||
|
||||
my $macro_prefix = uc($name).'_'.uc($field).'_';
|
||||
# Special handling for the common flags_type field
|
||||
$macro_prefix =~ s/FLAGS_TYPE_$/FLAGS_/ if ($field eq 'flags_type');
|
||||
# Special handling for _hi types
|
||||
$macro_prefix =~ s/_HI_/_/ if ($name =~ /_hi$/);
|
||||
|
||||
$macro_prefix =~ s/\[[0-9]+\]//;
|
||||
my %vmacros;
|
||||
my $vmacros_have_mask = 0;
|
||||
my @vmacros;
|
||||
my %subfields;
|
||||
my $all_single_bits=1;
|
||||
MACRO:
|
||||
foreach my $macro (@macros) {
|
||||
if ($macro =~ /^$macro_prefix(.*)_MASK$/) {
|
||||
my $macro = $&;
|
||||
my $maskdef = $macros{$macro};
|
||||
my $subfield = $1;
|
||||
my $subfield_value = "(data->$field & $macro)";
|
||||
if (defined $macros{"$macro_prefix$subfield\_SFT"}) {
|
||||
$subfield_value = "($subfield_value >> $macro_prefix$subfield\_SFT)";
|
||||
}
|
||||
$maskdef =~ s/[x0 ]//g;
|
||||
if ($type eq 'uint64_t') {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s $subfield = %%0*\" PRIX64 \"\\n\", %u, $subfield_value);\n", $max_field_len, '', length($maskdef);
|
||||
}
|
||||
else {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s $subfield = %%0*X\\n\", %u, $subfield_value);\n", $max_field_len, '', length($maskdef);
|
||||
}
|
||||
delete $$macroshash{$macro};
|
||||
}
|
||||
elsif ($macro =~ /^$macro_prefix(.*)_SFT$/) {
|
||||
delete $$macroshash{$macro};
|
||||
}
|
||||
elsif ($macro =~ /^$macro_prefix\MASK$/) {
|
||||
$vmacros_have_mask = 1;
|
||||
delete $$macroshash{$macro};
|
||||
}
|
||||
elsif ($macro =~ /^$macro_prefix(.*)$/) {
|
||||
my $macro = $&;
|
||||
my $subfield = $1;
|
||||
|
||||
# Check for longer fields with the same base... ie: link and link_speed
|
||||
foreach my $extra_field (@fields) {
|
||||
next if ($extra_field eq $field);
|
||||
if ($extra_field =~ /^$field/) {
|
||||
my $extra_prefix = uc($name).'_'.uc($extra_field).'_';
|
||||
next MACRO if ($macro =~ /^$extra_prefix/);
|
||||
}
|
||||
}
|
||||
|
||||
push @vmacros, $macro;
|
||||
my $macroeval = $macros{$macro};
|
||||
$macroeval =~ s/UINT32_C\((.*?)\)/$1/g;
|
||||
$vmacros{$macro} = eval("$macroeval");
|
||||
$subfields{$macro} = $subfield;
|
||||
|
||||
$all_single_bits = 0 if ($vmacros{$macro} & ($vmacros{$macro}-1));
|
||||
$all_single_bits = 0 if ($vmacros{$macro} == 0);
|
||||
}
|
||||
}
|
||||
if ($all_single_bits) {
|
||||
foreach my $macro (@vmacros) {
|
||||
my $subfield_value = "(data->$field & $macro)";
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s $subfields{$macro} : %%s\\n\", $subfield_value?\"ON\":\"OFF\");\n", $max_field_len, '';
|
||||
delete $$macroshash{$macro};
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf OUT "\tRTE_LOG(DEBUG, PMD, \" % *s Value : %%s\\n\",\n", $max_field_len, '';
|
||||
foreach my $macro (@vmacros) {
|
||||
my $subfield_value = "data->$field";
|
||||
$subfield_value = "($subfield_value & $macro_prefix\MASK)" if $vmacros_have_mask;
|
||||
print OUT "\t\t$subfield_value == $macro ? \"$subfields{$macro}\" :\n";
|
||||
delete $$macroshash{$macro};
|
||||
}
|
||||
print OUT "\t\t\"Unknown\");\n";
|
||||
}
|
||||
}
|
||||
|
||||
while ($header =~ /^typedef\s+struct\s+(.*?)\s+{(.*?)^}/msg) {
|
||||
my ($name,$def) = ($1, $2);
|
||||
my @fields=();
|
||||
my %type=();
|
||||
my @macros=();
|
||||
my %macros=();
|
||||
my $max_field_len=0;
|
||||
|
||||
# First, pull out all the fields in order...
|
||||
while($def =~ /^\s*([^\s#\/]+?)\s+([^;\/\s]+?)\s*;/mg) {
|
||||
my ($type, $name) = ($1, $2);
|
||||
push @fields, $name;
|
||||
$type{$name}=$type;
|
||||
$max_field_len = length($name) if length($name) > $max_field_len;
|
||||
}
|
||||
# Now, pull out the macros...
|
||||
while($def =~ /^\s*\#define\s+([^\s]+?)\s+(.*?)\s*$/mg) {
|
||||
push @macros, $1;
|
||||
$macros{$1}=$2;
|
||||
}
|
||||
|
||||
# Now, generate code to print the struct...
|
||||
print OUT "void decode_$name(const char *string __rte_unused, struct $name *data) {\n\tRTE_LOG(DEBUG, PMD, \"$name\\n\");\n";
|
||||
print HDR "void decode_$name(const char *string __rte_unused, struct $name *data);\n";
|
||||
$hdr_defs .= "#define decode_$name(x, y) {}\n";
|
||||
foreach my $field (@fields) {
|
||||
if ($field =~ /\[([0-9]+)\]/) {
|
||||
if ($type{$field} eq 'char') {
|
||||
print_single_val($field, $type{$field}, $max_field_len, $name, \%macros, \@macros, \@fields);
|
||||
}
|
||||
else {
|
||||
foreach my $idx (0..$1-1) {
|
||||
my $item = $field;
|
||||
$item =~ s/\[[0-9]+\]/[$idx]/;
|
||||
print_single_val($item, $type{$field}, $max_field_len, $name, \%macros, \@macros, \@fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
print_single_val($field, $type{$field}, $max_field_len, $name, \%macros, \@macros, \@fields);
|
||||
}
|
||||
}
|
||||
# print "Unhandled macros:\n",join("\n", keys %macros),"\n" if (keys %macros > 0);
|
||||
print OUT "}\n\n";
|
||||
}
|
||||
print OUT "#endif\n";
|
||||
|
||||
print HDR "#else\n";
|
||||
print HDR $hdr_defs;
|
||||
print HDR "#endif\n";
|
||||
close OUT;
|
||||
close HDR;
|
||||
}
|
||||
17576
sys/dev/bnxt/hsi_struct_def.h
Normal file
17576
sys/dev/bnxt/hsi_struct_def.h
Normal file
File diff suppressed because it is too large
Load diff
2358
sys/dev/bnxt/if_bnxt.c
Normal file
2358
sys/dev/bnxt/if_bnxt.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -57,6 +57,7 @@ SUBDIR= \
|
|||
${_bios} \
|
||||
${_bktr} \
|
||||
${_bm} \
|
||||
bnxt \
|
||||
bridgestp \
|
||||
bwi \
|
||||
bwn \
|
||||
|
|
|
|||
14
sys/modules/bnxt/Makefile
Normal file
14
sys/modules/bnxt/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#$FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/bnxt
|
||||
|
||||
KMOD = if_bnxt
|
||||
SRCS = device_if.h bus_if.h pci_if.h pci_iov_if.h ifdi_if.h
|
||||
SRCS += opt_inet.h opt_inet6.h opt_rss.h
|
||||
SRCS += bnxt_txrx.c if_bnxt.c
|
||||
SRCS += bnxt_hwrm.c bnxt_hwrm.h
|
||||
SRCS += bnxt_sysctl.c bnxt_sysctl.h
|
||||
|
||||
CFLAGS+= -DIFLIB
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
Loading…
Reference in a new issue