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:
Stephen Hurd 2016-11-15 20:35:29 +00:00
parent ba3eb10d85
commit d933e97f9d
17 changed files with 24183 additions and 0 deletions

View file

@ -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
View 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 .

View file

@ -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

View file

@ -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.

View file

@ -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
View 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

File diff suppressed because it is too large Load diff

102
sys/dev/bnxt/bnxt_hwrm.h Normal file
View 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
View 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
View 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;
}

View 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
View 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
View 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

File diff suppressed because it is too large Load diff

2358
sys/dev/bnxt/if_bnxt.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -57,6 +57,7 @@ SUBDIR= \
${_bios} \
${_bktr} \
${_bm} \
bnxt \
bridgestp \
bwi \
bwn \

14
sys/modules/bnxt/Makefile Normal file
View 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>