From owner-svn-src-head@freebsd.org Tue Nov 15 20:35:31 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2EA8EC43E01; Tue, 15 Nov 2016 20:35:31 +0000 (UTC) (envelope-from shurd@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BCD2316B7; Tue, 15 Nov 2016 20:35:30 +0000 (UTC) (envelope-from shurd@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uAFKZUjL045029; Tue, 15 Nov 2016 20:35:30 GMT (envelope-from shurd@FreeBSD.org) Received: (from shurd@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uAFKZTQB045021; Tue, 15 Nov 2016 20:35:29 GMT (envelope-from shurd@FreeBSD.org) Message-Id: <201611152035.uAFKZTQB045021@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: shurd set sender to shurd@FreeBSD.org using -f From: Stephen Hurd Date: Tue, 15 Nov 2016 20:35:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r308696 - in head: share/man/man4 sys/boot/forth sys/conf sys/dev/bnxt sys/modules sys/modules/bnxt X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Nov 2016 20:35:31 -0000 Author: shurd (ports committer) Date: Tue Nov 15 20:35:29 2016 New Revision: 308696 URL: https://svnweb.freebsd.org/changeset/base/308696 Log: 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 Added: head/share/man/man4/bnxt.4 (contents, props changed) head/sys/dev/bnxt/ head/sys/dev/bnxt/bnxt.h (contents, props changed) head/sys/dev/bnxt/bnxt_hwrm.c (contents, props changed) head/sys/dev/bnxt/bnxt_hwrm.h (contents, props changed) head/sys/dev/bnxt/bnxt_ioctl.h (contents, props changed) head/sys/dev/bnxt/bnxt_sysctl.c (contents, props changed) head/sys/dev/bnxt/bnxt_sysctl.h (contents, props changed) head/sys/dev/bnxt/bnxt_txrx.c (contents, props changed) head/sys/dev/bnxt/convert_hsi.pl (contents, props changed) head/sys/dev/bnxt/hsi_struct_def.h (contents, props changed) head/sys/dev/bnxt/if_bnxt.c (contents, props changed) head/sys/modules/bnxt/ head/sys/modules/bnxt/Makefile (contents, props changed) Modified: head/share/man/man4/Makefile head/sys/boot/forth/loader.conf head/sys/conf/NOTES head/sys/conf/files head/sys/modules/Makefile Modified: head/share/man/man4/Makefile ============================================================================== --- head/share/man/man4/Makefile Tue Nov 15 20:05:22 2016 (r308695) +++ head/share/man/man4/Makefile Tue Nov 15 20:35:29 2016 (r308696) @@ -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 Added: head/share/man/man4/bnxt.4 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/share/man/man4/bnxt.4 Tue Nov 15 20:35:29 2016 (r308696) @@ -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 . Modified: head/sys/boot/forth/loader.conf ============================================================================== --- head/sys/boot/forth/loader.conf Tue Nov 15 20:05:22 2016 (r308695) +++ head/sys/boot/forth/loader.conf Tue Nov 15 20:35:29 2016 (r308696) @@ -312,6 +312,7 @@ if_axe_load="NO" # ASIX Electronics AX8 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 Modified: head/sys/conf/NOTES ============================================================================== --- head/sys/conf/NOTES Tue Nov 15 20:05:22 2016 (r308695) +++ head/sys/conf/NOTES Tue Nov 15 20:35:29 2016 (r308696) @@ -1903,6 +1903,7 @@ device amphy # AMD AM79c873 / Davicom 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. Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Tue Nov 15 20:05:22 2016 (r308695) +++ head/sys/conf/files Tue Nov 15 20:35:29 2016 (r308696) @@ -1242,6 +1242,10 @@ dev/bktr/bktr_i2c.c optional bktr pci s 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 Added: head/sys/dev/bnxt/bnxt.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/bnxt/bnxt.h Tue Nov 15 20:35:29 2016 (r308696) @@ -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 +__FBSDID("$FreeBSD$"); + +#ifndef _BNXT_H +#define _BNXT_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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 */ Added: head/sys/dev/bnxt/bnxt_hwrm.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/bnxt/bnxt_hwrm.c Tue Nov 15 20:35:29 2016 (r308696) @@ -0,0 +1,1485 @@ +/*- + * 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 +__FBSDID("$FreeBSD$"); + +#include + +#include "bnxt.h" +#include "bnxt_hwrm.h" +#include "hsi_struct_def.h" + +static int bnxt_hwrm_err_map(uint16_t err); +static inline int _is_valid_ether_addr(uint8_t *); +static inline void get_random_ether_addr(uint8_t *); +static void bnxt_hwrm_set_link_common(struct bnxt_softc *softc, + struct hwrm_port_phy_cfg_input *req); +static void bnxt_hwrm_set_pause_common(struct bnxt_softc *softc, + struct hwrm_port_phy_cfg_input *req); +static void bnxt_hwrm_set_eee(struct bnxt_softc *softc, + struct hwrm_port_phy_cfg_input *req); +static int _hwrm_send_message(struct bnxt_softc *, void *, uint32_t); +static int hwrm_send_message(struct bnxt_softc *, void *, uint32_t); +static void bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *, void *, uint16_t); + +/* NVRam stuff has a five minute timeout */ +#define BNXT_NVM_TIMEO (5 * 60 * 1000) + +static int +bnxt_hwrm_err_map(uint16_t err) +{ + int rc; + + switch (err) { + case HWRM_ERR_CODE_SUCCESS: + return 0; + case HWRM_ERR_CODE_INVALID_PARAMS: + case HWRM_ERR_CODE_INVALID_FLAGS: + case HWRM_ERR_CODE_INVALID_ENABLES: + return EINVAL; + case HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED: + return EACCES; + case HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR: + return ENOMEM; + case HWRM_ERR_CODE_CMD_NOT_SUPPORTED: + return ENOSYS; + case HWRM_ERR_CODE_FAIL: + return EIO; + case HWRM_ERR_CODE_HWRM_ERROR: + case HWRM_ERR_CODE_UNKNOWN_ERR: + default: + return EDOOFUS; + } + + return rc; +} + +int +bnxt_alloc_hwrm_dma_mem(struct bnxt_softc *softc) +{ + int rc; + + rc = iflib_dma_alloc(softc->ctx, PAGE_SIZE, &softc->hwrm_cmd_resp, + BUS_DMA_NOWAIT); + return rc; +} + +void +bnxt_free_hwrm_dma_mem(struct bnxt_softc *softc) +{ + if (softc->hwrm_cmd_resp.idi_vaddr) + iflib_dma_free(&softc->hwrm_cmd_resp); + softc->hwrm_cmd_resp.idi_vaddr = NULL; + return; +} + +static void +bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *softc, void *request, + uint16_t req_type) +{ + struct input *req = request; + + req->req_type = htole16(req_type); + req->cmpl_ring = 0xffff; + req->target_id = 0xffff; + req->resp_addr = htole64(softc->hwrm_cmd_resp.idi_paddr); +} + +static int +_hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len) +{ + struct input *req = msg; + struct hwrm_err_output *resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; + uint32_t *data = msg; + int i; + uint16_t cp_ring_id; + uint8_t *valid; + uint16_t err; + + /* TODO: DMASYNC in here. */ + req->seq_id = htole16(softc->hwrm_cmd_seq++); + memset(resp, 0, PAGE_SIZE); + cp_ring_id = le16toh(req->cmpl_ring); + + /* Write request msg to hwrm channel */ + for (i = 0; i < msg_len; i += 4) { + bus_space_write_4(softc->hwrm_bar.tag, + softc->hwrm_bar.handle, + i, *data); + data++; + } + + /* Clear to the end of the request buffer */ + for (i = msg_len; i < HWRM_MAX_REQ_LEN; i += 4) + bus_space_write_4(softc->hwrm_bar.tag, softc->hwrm_bar.handle, + i, 0); + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***