1231437Sluigi/*- 2252869Sdelphij * Copyright (C) 2013 Emulex 3231437Sluigi * All rights reserved. 4231437Sluigi * 5231437Sluigi * Redistribution and use in source and binary forms, with or without 6231437Sluigi * modification, are permitted provided that the following conditions are met: 7231437Sluigi * 8231437Sluigi * 1. Redistributions of source code must retain the above copyright notice, 9231437Sluigi * this list of conditions and the following disclaimer. 10231437Sluigi * 11231437Sluigi * 2. Redistributions in binary form must reproduce the above copyright 12231437Sluigi * notice, this list of conditions and the following disclaimer in the 13231437Sluigi * documentation and/or other materials provided with the distribution. 14231437Sluigi * 15231437Sluigi * 3. Neither the name of the Emulex Corporation nor the names of its 16231437Sluigi * contributors may be used to endorse or promote products derived from 17231437Sluigi * this software without specific prior written permission. 18231437Sluigi * 19231437Sluigi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20231437Sluigi * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21231437Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22231437Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23231437Sluigi * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24231437Sluigi * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25231437Sluigi * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26231437Sluigi * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27231437Sluigi * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28231437Sluigi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29231437Sluigi * POSSIBILITY OF SUCH DAMAGE. 30231437Sluigi * 31231437Sluigi * Contact Information: 32231437Sluigi * freebsd-drivers@emulex.com 33231437Sluigi * 34231437Sluigi * Emulex 35231437Sluigi * 3333 Susan Street 36231437Sluigi * Costa Mesa, CA 92626 37231437Sluigi */ 38231437Sluigi 39231437Sluigi/* $FreeBSD$ */ 40231437Sluigi 41231437Sluigi#include <sys/param.h> 42231437Sluigi#include <sys/endian.h> 43231437Sluigi#include <sys/module.h> 44231437Sluigi#include <sys/kernel.h> 45231437Sluigi#include <sys/bus.h> 46231437Sluigi#include <sys/mbuf.h> 47231437Sluigi#include <sys/rman.h> 48231437Sluigi#include <sys/socket.h> 49231437Sluigi#include <sys/sockio.h> 50231437Sluigi#include <sys/sockopt.h> 51231437Sluigi#include <sys/queue.h> 52231437Sluigi#include <sys/taskqueue.h> 53231437Sluigi#include <sys/lock.h> 54231437Sluigi#include <sys/mutex.h> 55231437Sluigi#include <sys/sysctl.h> 56231437Sluigi#include <sys/random.h> 57231437Sluigi#include <sys/firmware.h> 58231437Sluigi#include <sys/systm.h> 59231437Sluigi#include <sys/proc.h> 60231437Sluigi 61231437Sluigi#include <dev/pci/pcireg.h> 62231437Sluigi#include <dev/pci/pcivar.h> 63231437Sluigi 64231437Sluigi#include <net/bpf.h> 65231437Sluigi#include <net/ethernet.h> 66231437Sluigi#include <net/if.h> 67231437Sluigi#include <net/if_types.h> 68231437Sluigi#include <net/if_media.h> 69231437Sluigi#include <net/if_vlan_var.h> 70231437Sluigi#include <net/if_dl.h> 71231437Sluigi 72231437Sluigi#include <netinet/in.h> 73231437Sluigi#include <netinet/in_systm.h> 74231437Sluigi#include <netinet/in_var.h> 75231437Sluigi#include <netinet/if_ether.h> 76231437Sluigi#include <netinet/ip.h> 77231437Sluigi#include <netinet/ip6.h> 78231437Sluigi#include <netinet6/in6_var.h> 79231437Sluigi#include <netinet6/ip6_mroute.h> 80231437Sluigi 81231437Sluigi#include <netinet/udp.h> 82231437Sluigi#include <netinet/tcp.h> 83231437Sluigi#include <netinet/sctp.h> 84231437Sluigi#include <netinet/tcp_lro.h> 85231437Sluigi 86231437Sluigi#include <machine/bus.h> 87231437Sluigi 88231437Sluigi#include "oce_hw.h" 89231437Sluigi 90257187Sdelphij/* OCE device driver module component revision informaiton */ 91257187Sdelphij#define COMPONENT_REVISION "10.0.664.0" 92231437Sluigi 93231437Sluigi/* OCE devices supported by this driver */ 94231437Sluigi#define PCI_VENDOR_EMULEX 0x10df /* Emulex */ 95231437Sluigi#define PCI_VENDOR_SERVERENGINES 0x19a2 /* ServerEngines (BE) */ 96231437Sluigi#define PCI_PRODUCT_BE2 0x0700 /* BE2 network adapter */ 97231437Sluigi#define PCI_PRODUCT_BE3 0x0710 /* BE3 network adapter */ 98231437Sluigi#define PCI_PRODUCT_XE201 0xe220 /* XE201 network adapter */ 99231437Sluigi#define PCI_PRODUCT_XE201_VF 0xe228 /* XE201 with VF in Lancer */ 100252869Sdelphij#define PCI_PRODUCT_SH 0x0720 /* Skyhawk network adapter */ 101231437Sluigi 102231437Sluigi#define IS_BE(sc) (((sc->flags & OCE_FLAGS_BE3) | \ 103231437Sluigi (sc->flags & OCE_FLAGS_BE2))? 1:0) 104252869Sdelphij#define IS_BE3(sc) (sc->flags & OCE_FLAGS_BE3) 105252869Sdelphij#define IS_BE2(sc) (sc->flags & OCE_FLAGS_BE2) 106231437Sluigi#define IS_XE201(sc) ((sc->flags & OCE_FLAGS_XE201) ? 1:0) 107231437Sluigi#define HAS_A0_CHIP(sc) ((sc->flags & OCE_FLAGS_HAS_A0_CHIP) ? 1:0) 108252869Sdelphij#define IS_SH(sc) ((sc->flags & OCE_FLAGS_SH) ? 1 : 0) 109231437Sluigi 110252869Sdelphij#define is_be_mode_mc(sc) ((sc->function_mode & FNM_FLEX10_MODE) || \ 111252869Sdelphij (sc->function_mode & FNM_UMC_MODE) || \ 112252869Sdelphij (sc->function_mode & FNM_VNIC_MODE)) 113252869Sdelphij#define OCE_FUNCTION_CAPS_SUPER_NIC 0x40 114252869Sdelphij#define IS_PROFILE_SUPER_NIC(sc) (sc->function_caps & OCE_FUNCTION_CAPS_SUPER_NIC) 115231437Sluigi 116252869Sdelphij 117231437Sluigi/* proportion Service Level Interface queues */ 118231437Sluigi#define OCE_MAX_UNITS 2 119231437Sluigi#define OCE_MAX_PPORT OCE_MAX_UNITS 120231437Sluigi#define OCE_MAX_VPORT OCE_MAX_UNITS 121231437Sluigi 122231437Sluigiextern int mp_ncpus; /* system's total active cpu cores */ 123231437Sluigi#define OCE_NCPUS mp_ncpus 124231879Sluigi 125231879Sluigi/* This should be powers of 2. Like 2,4,8 & 16 */ 126252869Sdelphij#define OCE_MAX_RSS 8 127231437Sluigi#define OCE_LEGACY_MODE_RSS 4 /* For BE3 Legacy mode*/ 128252869Sdelphij#define is_rss_enabled(sc) ((sc->function_caps & FNC_RSS) && !is_be_mode_mc(sc)) 129231437Sluigi 130231437Sluigi#define OCE_MIN_RQ 1 131231437Sluigi#define OCE_MIN_WQ 1 132231437Sluigi 133231437Sluigi#define OCE_MAX_RQ OCE_MAX_RSS + 1 /* one default queue */ 134231437Sluigi#define OCE_MAX_WQ 8 135231437Sluigi 136231437Sluigi#define OCE_MAX_EQ 32 137231437Sluigi#define OCE_MAX_CQ OCE_MAX_RQ + OCE_MAX_WQ + 1 /* one MCC queue */ 138231437Sluigi#define OCE_MAX_CQ_EQ 8 /* Max CQ that can attached to an EQ */ 139231437Sluigi 140231437Sluigi#define OCE_DEFAULT_WQ_EQD 16 141231437Sluigi#define OCE_MAX_PACKET_Q 16 142231437Sluigi#define OCE_RQ_BUF_SIZE 2048 143231437Sluigi#define OCE_LSO_MAX_SIZE (64 * 1024) 144231437Sluigi#define LONG_TIMEOUT 30 145247880Sdelphij#define OCE_MAX_JUMBO_FRAME_SIZE 9018 146231437Sluigi#define OCE_MAX_MTU (OCE_MAX_JUMBO_FRAME_SIZE - \ 147231437Sluigi ETHER_VLAN_ENCAP_LEN - \ 148231437Sluigi ETHER_HDR_LEN) 149231437Sluigi 150231437Sluigi#define OCE_MAX_TX_ELEMENTS 29 151231437Sluigi#define OCE_MAX_TX_DESC 1024 152231437Sluigi#define OCE_MAX_TX_SIZE 65535 153231437Sluigi#define OCE_MAX_RX_SIZE 4096 154231437Sluigi#define OCE_MAX_RQ_POSTS 255 155231437Sluigi#define OCE_DEFAULT_PROMISCUOUS 0 156231437Sluigi 157231437Sluigi 158231437Sluigi#define RSS_ENABLE_IPV4 0x1 159231437Sluigi#define RSS_ENABLE_TCP_IPV4 0x2 160231437Sluigi#define RSS_ENABLE_IPV6 0x4 161231437Sluigi#define RSS_ENABLE_TCP_IPV6 0x8 162231437Sluigi 163252869Sdelphij#define INDIRECTION_TABLE_ENTRIES 128 164231437Sluigi 165231437Sluigi/* flow control definitions */ 166231437Sluigi#define OCE_FC_NONE 0x00000000 167231437Sluigi#define OCE_FC_TX 0x00000001 168231437Sluigi#define OCE_FC_RX 0x00000002 169231437Sluigi#define OCE_DEFAULT_FLOW_CONTROL (OCE_FC_TX | OCE_FC_RX) 170231437Sluigi 171231437Sluigi 172231437Sluigi/* Interface capabilities to give device when creating interface */ 173231437Sluigi#define OCE_CAPAB_FLAGS (MBX_RX_IFACE_FLAGS_BROADCAST | \ 174231437Sluigi MBX_RX_IFACE_FLAGS_UNTAGGED | \ 175231437Sluigi MBX_RX_IFACE_FLAGS_PROMISCUOUS | \ 176257187Sdelphij MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS | \ 177231437Sluigi MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS | \ 178231437Sluigi MBX_RX_IFACE_FLAGS_RSS | \ 179231437Sluigi MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR) 180231437Sluigi 181231437Sluigi/* Interface capabilities to enable by default (others set dynamically) */ 182231437Sluigi#define OCE_CAPAB_ENABLE (MBX_RX_IFACE_FLAGS_BROADCAST | \ 183231437Sluigi MBX_RX_IFACE_FLAGS_UNTAGGED | \ 184231437Sluigi MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR) 185231437Sluigi 186231437Sluigi#define OCE_IF_HWASSIST (CSUM_IP | CSUM_TCP | CSUM_UDP) 187231437Sluigi#define OCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ 188231437Sluigi IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \ 189231879Sluigi IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU) 190231437Sluigi#define OCE_IF_HWASSIST_NONE 0 191231437Sluigi#define OCE_IF_CAPABILITIES_NONE 0 192231437Sluigi 193231437Sluigi 194231437Sluigi#define ETH_ADDR_LEN 6 195231437Sluigi#define MAX_VLANFILTER_SIZE 64 196231437Sluigi#define MAX_VLANS 4096 197231437Sluigi 198231437Sluigi#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16)) 199231437Sluigi#define BSWAP_8(x) ((x) & 0xff) 200231437Sluigi#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) 201231437Sluigi#define BSWAP_32(x) ((BSWAP_16(x) << 16) | \ 202231437Sluigi BSWAP_16((x) >> 16)) 203231437Sluigi#define BSWAP_64(x) ((BSWAP_32(x) << 32) | \ 204231437Sluigi BSWAP_32((x) >> 32)) 205231437Sluigi 206231437Sluigi#define for_all_wq_queues(sc, wq, i) \ 207231437Sluigi for (i = 0, wq = sc->wq[0]; i < sc->nwqs; i++, wq = sc->wq[i]) 208231437Sluigi#define for_all_rq_queues(sc, rq, i) \ 209231437Sluigi for (i = 0, rq = sc->rq[0]; i < sc->nrqs; i++, rq = sc->rq[i]) 210252869Sdelphij#define for_all_rss_queues(sc, rq, i) \ 211252869Sdelphij for (i = 0, rq = sc->rq[i + 1]; i < (sc->nrqs - 1); \ 212252869Sdelphij i++, rq = sc->rq[i + 1]) 213231437Sluigi#define for_all_evnt_queues(sc, eq, i) \ 214231437Sluigi for (i = 0, eq = sc->eq[0]; i < sc->neqs; i++, eq = sc->eq[i]) 215231437Sluigi#define for_all_cq_queues(sc, cq, i) \ 216231437Sluigi for (i = 0, cq = sc->cq[0]; i < sc->ncqs; i++, cq = sc->cq[i]) 217231437Sluigi 218231437Sluigi 219231437Sluigi/* Flash specific */ 220231437Sluigi#define IOCTL_COOKIE "SERVERENGINES CORP" 221231437Sluigi#define MAX_FLASH_COMP 32 222231437Sluigi 223231437Sluigi#define IMG_ISCSI 160 224231437Sluigi#define IMG_REDBOOT 224 225231437Sluigi#define IMG_BIOS 34 226231437Sluigi#define IMG_PXEBIOS 32 227231437Sluigi#define IMG_FCOEBIOS 33 228231437Sluigi#define IMG_ISCSI_BAK 176 229231437Sluigi#define IMG_FCOE 162 230231437Sluigi#define IMG_FCOE_BAK 178 231231437Sluigi#define IMG_NCSI 16 232231437Sluigi#define IMG_PHY 192 233231437Sluigi#define FLASHROM_OPER_FLASH 1 234231437Sluigi#define FLASHROM_OPER_SAVE 2 235231437Sluigi#define FLASHROM_OPER_REPORT 4 236231437Sluigi#define FLASHROM_OPER_FLASH_PHY 9 237231437Sluigi#define FLASHROM_OPER_SAVE_PHY 10 238231437Sluigi#define TN_8022 13 239231437Sluigi 240231437Sluigienum { 241231437Sluigi PHY_TYPE_CX4_10GB = 0, 242231437Sluigi PHY_TYPE_XFP_10GB, 243231437Sluigi PHY_TYPE_SFP_1GB, 244231437Sluigi PHY_TYPE_SFP_PLUS_10GB, 245231437Sluigi PHY_TYPE_KR_10GB, 246231437Sluigi PHY_TYPE_KX4_10GB, 247231437Sluigi PHY_TYPE_BASET_10GB, 248231437Sluigi PHY_TYPE_BASET_1GB, 249231437Sluigi PHY_TYPE_BASEX_1GB, 250231437Sluigi PHY_TYPE_SGMII, 251231437Sluigi PHY_TYPE_DISABLED = 255 252231437Sluigi}; 253231437Sluigi 254231437Sluigi/** 255231437Sluigi * @brief Define and hold all necessary info for a single interrupt 256231437Sluigi */ 257231437Sluigi#define OCE_MAX_MSI 32 /* Message Signaled Interrupts */ 258231437Sluigi#define OCE_MAX_MSIX 2048 /* PCI Express MSI Interrrupts */ 259231437Sluigi 260231437Sluigitypedef struct oce_intr_info { 261231437Sluigi void *tag; /* cookie returned by bus_setup_intr */ 262231437Sluigi struct resource *intr_res; /* PCI resource container */ 263231437Sluigi int irq_rr; /* resource id for the interrupt */ 264231437Sluigi struct oce_softc *sc; /* pointer to the parent soft c */ 265231437Sluigi struct oce_eq *eq; /* pointer to the connected EQ */ 266231437Sluigi struct taskqueue *tq; /* Associated task queue */ 267231437Sluigi struct task task; /* task queue task */ 268231437Sluigi char task_name[32]; /* task name */ 269231437Sluigi int vector; /* interrupt vector number */ 270231437Sluigi} OCE_INTR_INFO, *POCE_INTR_INFO; 271231437Sluigi 272231437Sluigi 273231437Sluigi/* Ring related */ 274231437Sluigi#define GET_Q_NEXT(_START, _STEP, _END) \ 275231437Sluigi (((_START) + (_STEP)) < (_END) ? ((_START) + (_STEP)) \ 276231437Sluigi : (((_START) + (_STEP)) - (_END))) 277231437Sluigi 278231437Sluigi#define DBUF_PA(obj) ((obj)->addr) 279231437Sluigi#define DBUF_VA(obj) ((obj)->ptr) 280231437Sluigi#define DBUF_TAG(obj) ((obj)->tag) 281231437Sluigi#define DBUF_MAP(obj) ((obj)->map) 282231437Sluigi#define DBUF_SYNC(obj, flags) \ 283231437Sluigi (void) bus_dmamap_sync(DBUF_TAG(obj), DBUF_MAP(obj), (flags)) 284231437Sluigi 285231437Sluigi#define RING_NUM_PENDING(ring) ring->num_used 286231437Sluigi#define RING_FULL(ring) (ring->num_used == ring->num_items) 287231437Sluigi#define RING_EMPTY(ring) (ring->num_used == 0) 288231437Sluigi#define RING_NUM_FREE(ring) \ 289231437Sluigi (uint32_t)(ring->num_items - ring->num_used) 290231437Sluigi#define RING_GET(ring, n) \ 291231437Sluigi ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items) 292231437Sluigi#define RING_PUT(ring, n) \ 293231437Sluigi ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items) 294231437Sluigi 295231437Sluigi#define RING_GET_CONSUMER_ITEM_VA(ring, type) \ 296231437Sluigi (void*)((type *)DBUF_VA(&ring->dma) + ring->cidx) 297231437Sluigi#define RING_GET_CONSUMER_ITEM_PA(ring, type) \ 298231437Sluigi (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx) 299231437Sluigi#define RING_GET_PRODUCER_ITEM_VA(ring, type) \ 300231437Sluigi (void *)(((type *)DBUF_VA(&ring->dma)) + ring->pidx) 301231437Sluigi#define RING_GET_PRODUCER_ITEM_PA(ring, type) \ 302231437Sluigi (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx) 303231437Sluigi 304231437Sluigi#define OCE_DMAPTR(o, c) ((c *)(o)->ptr) 305231437Sluigi 306231437Sluigistruct oce_packet_desc { 307231437Sluigi struct mbuf *mbuf; 308231437Sluigi bus_dmamap_t map; 309231437Sluigi int nsegs; 310231437Sluigi uint32_t wqe_idx; 311231437Sluigi}; 312231437Sluigi 313231437Sluigitypedef struct oce_dma_mem { 314231437Sluigi bus_dma_tag_t tag; 315231437Sluigi bus_dmamap_t map; 316231437Sluigi void *ptr; 317231437Sluigi bus_addr_t paddr; 318231437Sluigi} OCE_DMA_MEM, *POCE_DMA_MEM; 319231437Sluigi 320231437Sluigitypedef struct oce_ring_buffer_s { 321231437Sluigi uint16_t cidx; /* Get ptr */ 322231437Sluigi uint16_t pidx; /* Put Ptr */ 323231437Sluigi size_t item_size; 324231437Sluigi size_t num_items; 325231437Sluigi uint32_t num_used; 326231437Sluigi OCE_DMA_MEM dma; 327231437Sluigi} oce_ring_buffer_t; 328231437Sluigi 329231437Sluigi/* Stats */ 330231437Sluigi#define OCE_UNICAST_PACKET 0 331231437Sluigi#define OCE_MULTICAST_PACKET 1 332231437Sluigi#define OCE_BROADCAST_PACKET 2 333231437Sluigi#define OCE_RSVD_PACKET 3 334231437Sluigi 335231437Sluigistruct oce_rx_stats { 336231437Sluigi /* Total Receive Stats*/ 337231437Sluigi uint64_t t_rx_pkts; 338231437Sluigi uint64_t t_rx_bytes; 339231437Sluigi uint32_t t_rx_frags; 340231437Sluigi uint32_t t_rx_mcast_pkts; 341231437Sluigi uint32_t t_rx_ucast_pkts; 342231437Sluigi uint32_t t_rxcp_errs; 343231437Sluigi}; 344231437Sluigistruct oce_tx_stats { 345231437Sluigi /*Total Transmit Stats */ 346231437Sluigi uint64_t t_tx_pkts; 347231437Sluigi uint64_t t_tx_bytes; 348231437Sluigi uint32_t t_tx_reqs; 349231437Sluigi uint32_t t_tx_stops; 350231437Sluigi uint32_t t_tx_wrbs; 351231437Sluigi uint32_t t_tx_compl; 352231437Sluigi uint32_t t_ipv6_ext_hdr_tx_drop; 353231437Sluigi}; 354231437Sluigi 355231437Sluigistruct oce_be_stats { 356231437Sluigi uint8_t be_on_die_temperature; 357231437Sluigi uint32_t be_tx_events; 358231437Sluigi uint32_t eth_red_drops; 359231437Sluigi uint32_t rx_drops_no_pbuf; 360231437Sluigi uint32_t rx_drops_no_txpb; 361231437Sluigi uint32_t rx_drops_no_erx_descr; 362231437Sluigi uint32_t rx_drops_no_tpre_descr; 363231437Sluigi uint32_t rx_drops_too_many_frags; 364231437Sluigi uint32_t rx_drops_invalid_ring; 365231437Sluigi uint32_t forwarded_packets; 366231437Sluigi uint32_t rx_drops_mtu; 367231437Sluigi uint32_t rx_crc_errors; 368231437Sluigi uint32_t rx_alignment_symbol_errors; 369231437Sluigi uint32_t rx_pause_frames; 370231437Sluigi uint32_t rx_priority_pause_frames; 371231437Sluigi uint32_t rx_control_frames; 372231437Sluigi uint32_t rx_in_range_errors; 373231437Sluigi uint32_t rx_out_range_errors; 374231437Sluigi uint32_t rx_frame_too_long; 375231437Sluigi uint32_t rx_address_match_errors; 376231437Sluigi uint32_t rx_dropped_too_small; 377231437Sluigi uint32_t rx_dropped_too_short; 378231437Sluigi uint32_t rx_dropped_header_too_small; 379231437Sluigi uint32_t rx_dropped_tcp_length; 380231437Sluigi uint32_t rx_dropped_runt; 381231437Sluigi uint32_t rx_ip_checksum_errs; 382231437Sluigi uint32_t rx_tcp_checksum_errs; 383231437Sluigi uint32_t rx_udp_checksum_errs; 384231437Sluigi uint32_t rx_switched_unicast_packets; 385231437Sluigi uint32_t rx_switched_multicast_packets; 386231437Sluigi uint32_t rx_switched_broadcast_packets; 387231437Sluigi uint32_t tx_pauseframes; 388231437Sluigi uint32_t tx_priority_pauseframes; 389231437Sluigi uint32_t tx_controlframes; 390231437Sluigi uint32_t rxpp_fifo_overflow_drop; 391231437Sluigi uint32_t rx_input_fifo_overflow_drop; 392231437Sluigi uint32_t pmem_fifo_overflow_drop; 393231437Sluigi uint32_t jabber_events; 394231437Sluigi}; 395231437Sluigi 396231437Sluigistruct oce_xe201_stats { 397231437Sluigi uint64_t tx_pkts; 398231437Sluigi uint64_t tx_unicast_pkts; 399231437Sluigi uint64_t tx_multicast_pkts; 400231437Sluigi uint64_t tx_broadcast_pkts; 401231437Sluigi uint64_t tx_bytes; 402231437Sluigi uint64_t tx_unicast_bytes; 403231437Sluigi uint64_t tx_multicast_bytes; 404231437Sluigi uint64_t tx_broadcast_bytes; 405231437Sluigi uint64_t tx_discards; 406231437Sluigi uint64_t tx_errors; 407231437Sluigi uint64_t tx_pause_frames; 408231437Sluigi uint64_t tx_pause_on_frames; 409231437Sluigi uint64_t tx_pause_off_frames; 410231437Sluigi uint64_t tx_internal_mac_errors; 411231437Sluigi uint64_t tx_control_frames; 412231437Sluigi uint64_t tx_pkts_64_bytes; 413231437Sluigi uint64_t tx_pkts_65_to_127_bytes; 414231437Sluigi uint64_t tx_pkts_128_to_255_bytes; 415231437Sluigi uint64_t tx_pkts_256_to_511_bytes; 416231437Sluigi uint64_t tx_pkts_512_to_1023_bytes; 417231437Sluigi uint64_t tx_pkts_1024_to_1518_bytes; 418231437Sluigi uint64_t tx_pkts_1519_to_2047_bytes; 419231437Sluigi uint64_t tx_pkts_2048_to_4095_bytes; 420231437Sluigi uint64_t tx_pkts_4096_to_8191_bytes; 421231437Sluigi uint64_t tx_pkts_8192_to_9216_bytes; 422231437Sluigi uint64_t tx_lso_pkts; 423231437Sluigi uint64_t rx_pkts; 424231437Sluigi uint64_t rx_unicast_pkts; 425231437Sluigi uint64_t rx_multicast_pkts; 426231437Sluigi uint64_t rx_broadcast_pkts; 427231437Sluigi uint64_t rx_bytes; 428231437Sluigi uint64_t rx_unicast_bytes; 429231437Sluigi uint64_t rx_multicast_bytes; 430231437Sluigi uint64_t rx_broadcast_bytes; 431231437Sluigi uint32_t rx_unknown_protos; 432231437Sluigi uint64_t rx_discards; 433231437Sluigi uint64_t rx_errors; 434231437Sluigi uint64_t rx_crc_errors; 435231437Sluigi uint64_t rx_alignment_errors; 436231437Sluigi uint64_t rx_symbol_errors; 437231437Sluigi uint64_t rx_pause_frames; 438231437Sluigi uint64_t rx_pause_on_frames; 439231437Sluigi uint64_t rx_pause_off_frames; 440231437Sluigi uint64_t rx_frames_too_long; 441231437Sluigi uint64_t rx_internal_mac_errors; 442231437Sluigi uint32_t rx_undersize_pkts; 443231437Sluigi uint32_t rx_oversize_pkts; 444231437Sluigi uint32_t rx_fragment_pkts; 445231437Sluigi uint32_t rx_jabbers; 446231437Sluigi uint64_t rx_control_frames; 447231437Sluigi uint64_t rx_control_frames_unknown_opcode; 448231437Sluigi uint32_t rx_in_range_errors; 449231437Sluigi uint32_t rx_out_of_range_errors; 450231437Sluigi uint32_t rx_address_match_errors; 451231437Sluigi uint32_t rx_vlan_mismatch_errors; 452231437Sluigi uint32_t rx_dropped_too_small; 453231437Sluigi uint32_t rx_dropped_too_short; 454231437Sluigi uint32_t rx_dropped_header_too_small; 455231437Sluigi uint32_t rx_dropped_invalid_tcp_length; 456231437Sluigi uint32_t rx_dropped_runt; 457231437Sluigi uint32_t rx_ip_checksum_errors; 458231437Sluigi uint32_t rx_tcp_checksum_errors; 459231437Sluigi uint32_t rx_udp_checksum_errors; 460231437Sluigi uint32_t rx_non_rss_pkts; 461231437Sluigi uint64_t rx_ipv4_pkts; 462231437Sluigi uint64_t rx_ipv6_pkts; 463231437Sluigi uint64_t rx_ipv4_bytes; 464231437Sluigi uint64_t rx_ipv6_bytes; 465231437Sluigi uint64_t rx_nic_pkts; 466231437Sluigi uint64_t rx_tcp_pkts; 467231437Sluigi uint64_t rx_iscsi_pkts; 468231437Sluigi uint64_t rx_management_pkts; 469231437Sluigi uint64_t rx_switched_unicast_pkts; 470231437Sluigi uint64_t rx_switched_multicast_pkts; 471231437Sluigi uint64_t rx_switched_broadcast_pkts; 472231437Sluigi uint64_t num_forwards; 473231437Sluigi uint32_t rx_fifo_overflow; 474231437Sluigi uint32_t rx_input_fifo_overflow; 475231437Sluigi uint64_t rx_drops_too_many_frags; 476231437Sluigi uint32_t rx_drops_invalid_queue; 477231437Sluigi uint64_t rx_drops_mtu; 478231437Sluigi uint64_t rx_pkts_64_bytes; 479231437Sluigi uint64_t rx_pkts_65_to_127_bytes; 480231437Sluigi uint64_t rx_pkts_128_to_255_bytes; 481231437Sluigi uint64_t rx_pkts_256_to_511_bytes; 482231437Sluigi uint64_t rx_pkts_512_to_1023_bytes; 483231437Sluigi uint64_t rx_pkts_1024_to_1518_bytes; 484231437Sluigi uint64_t rx_pkts_1519_to_2047_bytes; 485231437Sluigi uint64_t rx_pkts_2048_to_4095_bytes; 486231437Sluigi uint64_t rx_pkts_4096_to_8191_bytes; 487231437Sluigi uint64_t rx_pkts_8192_to_9216_bytes; 488231437Sluigi}; 489231437Sluigi 490231437Sluigistruct oce_drv_stats { 491231437Sluigi struct oce_rx_stats rx; 492231437Sluigi struct oce_tx_stats tx; 493231437Sluigi union { 494231437Sluigi struct oce_be_stats be; 495231437Sluigi struct oce_xe201_stats xe201; 496231437Sluigi } u0; 497231437Sluigi}; 498231437Sluigi 499247880Sdelphij#define INTR_RATE_HWM 15000 500247880Sdelphij#define INTR_RATE_LWM 10000 501231437Sluigi 502247880Sdelphij#define OCE_MAX_EQD 128u 503247880Sdelphij#define OCE_MIN_EQD 50u 504231437Sluigi 505247880Sdelphijstruct oce_set_eqd { 506247880Sdelphij uint32_t eq_id; 507247880Sdelphij uint32_t phase; 508247880Sdelphij uint32_t delay_multiplier; 509247880Sdelphij}; 510247880Sdelphij 511247880Sdelphijstruct oce_aic_obj { /* Adaptive interrupt coalescing (AIC) info */ 512247880Sdelphij boolean_t enable; 513247880Sdelphij uint32_t min_eqd; /* in usecs */ 514247880Sdelphij uint32_t max_eqd; /* in usecs */ 515247880Sdelphij uint32_t cur_eqd; /* in usecs */ 516247880Sdelphij uint32_t et_eqd; /* configured value when aic is off */ 517247880Sdelphij uint64_t ticks; 518247880Sdelphij uint64_t intr_prev; 519247880Sdelphij}; 520247880Sdelphij 521231437Sluigi#define MAX_LOCK_DESC_LEN 32 522231437Sluigistruct oce_lock { 523231437Sluigi struct mtx mutex; 524231437Sluigi char name[MAX_LOCK_DESC_LEN+1]; 525231437Sluigi}; 526231437Sluigi#define OCE_LOCK struct oce_lock 527231437Sluigi 528231437Sluigi#define LOCK_CREATE(lock, desc) { \ 529231437Sluigi strncpy((lock)->name, (desc), MAX_LOCK_DESC_LEN); \ 530231437Sluigi (lock)->name[MAX_LOCK_DESC_LEN] = '\0'; \ 531246799Sjpaetzel mtx_init(&(lock)->mutex, (lock)->name, NULL, MTX_DEF); \ 532231437Sluigi} 533231437Sluigi#define LOCK_DESTROY(lock) \ 534231437Sluigi if (mtx_initialized(&(lock)->mutex))\ 535231437Sluigi mtx_destroy(&(lock)->mutex) 536231437Sluigi#define TRY_LOCK(lock) mtx_trylock(&(lock)->mutex) 537231437Sluigi#define LOCK(lock) mtx_lock(&(lock)->mutex) 538231437Sluigi#define LOCKED(lock) mtx_owned(&(lock)->mutex) 539231437Sluigi#define UNLOCK(lock) mtx_unlock(&(lock)->mutex) 540231437Sluigi 541231437Sluigi#define DEFAULT_MQ_MBOX_TIMEOUT (5 * 1000 * 1000) 542231437Sluigi#define MBX_READY_TIMEOUT (1 * 1000 * 1000) 543231437Sluigi#define DEFAULT_DRAIN_TIME 200 544231437Sluigi#define MBX_TIMEOUT_SEC 5 545231437Sluigi#define STAT_TIMEOUT 2000000 546231437Sluigi 547231437Sluigi/* size of the packet descriptor array in a transmit queue */ 548231437Sluigi#define OCE_TX_RING_SIZE 2048 549231437Sluigi#define OCE_RX_RING_SIZE 1024 550231437Sluigi#define OCE_WQ_PACKET_ARRAY_SIZE (OCE_TX_RING_SIZE/2) 551231437Sluigi#define OCE_RQ_PACKET_ARRAY_SIZE (OCE_RX_RING_SIZE) 552231437Sluigi 553231437Sluigistruct oce_dev; 554231437Sluigi 555231437Sluigienum eq_len { 556231437Sluigi EQ_LEN_256 = 256, 557231437Sluigi EQ_LEN_512 = 512, 558231437Sluigi EQ_LEN_1024 = 1024, 559231437Sluigi EQ_LEN_2048 = 2048, 560231437Sluigi EQ_LEN_4096 = 4096 561231437Sluigi}; 562231437Sluigi 563231437Sluigienum eqe_size { 564231437Sluigi EQE_SIZE_4 = 4, 565231437Sluigi EQE_SIZE_16 = 16 566231437Sluigi}; 567231437Sluigi 568231437Sluigienum qtype { 569231437Sluigi QTYPE_EQ, 570231437Sluigi QTYPE_MQ, 571231437Sluigi QTYPE_WQ, 572231437Sluigi QTYPE_RQ, 573231437Sluigi QTYPE_CQ, 574231437Sluigi QTYPE_RSS 575231437Sluigi}; 576231437Sluigi 577231437Sluigitypedef enum qstate_e { 578231437Sluigi QDELETED = 0x0, 579231437Sluigi QCREATED = 0x1 580231437Sluigi} qstate_t; 581231437Sluigi 582231437Sluigistruct eq_config { 583231437Sluigi enum eq_len q_len; 584231437Sluigi enum eqe_size item_size; 585231437Sluigi uint32_t q_vector_num; 586231437Sluigi uint8_t min_eqd; 587231437Sluigi uint8_t max_eqd; 588231437Sluigi uint8_t cur_eqd; 589231437Sluigi uint8_t pad; 590231437Sluigi}; 591231437Sluigi 592231437Sluigistruct oce_eq { 593231437Sluigi uint32_t eq_id; 594231437Sluigi void *parent; 595231437Sluigi void *cb_context; 596231437Sluigi oce_ring_buffer_t *ring; 597231437Sluigi uint32_t ref_count; 598231437Sluigi qstate_t qstate; 599231437Sluigi struct oce_cq *cq[OCE_MAX_CQ_EQ]; 600231437Sluigi int cq_valid; 601231437Sluigi struct eq_config eq_cfg; 602231437Sluigi int vector; 603247880Sdelphij uint64_t intr; 604231437Sluigi}; 605231437Sluigi 606231437Sluigienum cq_len { 607231437Sluigi CQ_LEN_256 = 256, 608231437Sluigi CQ_LEN_512 = 512, 609231437Sluigi CQ_LEN_1024 = 1024 610231437Sluigi}; 611231437Sluigi 612231437Sluigistruct cq_config { 613231437Sluigi enum cq_len q_len; 614231437Sluigi uint32_t item_size; 615231437Sluigi boolean_t is_eventable; 616231437Sluigi boolean_t sol_eventable; 617231437Sluigi boolean_t nodelay; 618231437Sluigi uint16_t dma_coalescing; 619231437Sluigi}; 620231437Sluigi 621231437Sluigitypedef uint16_t(*cq_handler_t) (void *arg1); 622231437Sluigi 623231437Sluigistruct oce_cq { 624231437Sluigi uint32_t cq_id; 625231437Sluigi void *parent; 626231437Sluigi struct oce_eq *eq; 627231437Sluigi cq_handler_t cq_handler; 628231437Sluigi void *cb_arg; 629231437Sluigi oce_ring_buffer_t *ring; 630231437Sluigi qstate_t qstate; 631231437Sluigi struct cq_config cq_cfg; 632231437Sluigi uint32_t ref_count; 633231437Sluigi}; 634231437Sluigi 635231437Sluigi 636231437Sluigistruct mq_config { 637231437Sluigi uint32_t eqd; 638231437Sluigi uint8_t q_len; 639231437Sluigi uint8_t pad[3]; 640231437Sluigi}; 641231437Sluigi 642231437Sluigi 643231437Sluigistruct oce_mq { 644231437Sluigi void *parent; 645231437Sluigi oce_ring_buffer_t *ring; 646231437Sluigi uint32_t mq_id; 647231437Sluigi struct oce_cq *cq; 648231437Sluigi struct oce_cq *async_cq; 649231437Sluigi uint32_t mq_free; 650231437Sluigi qstate_t qstate; 651231437Sluigi struct mq_config cfg; 652231437Sluigi}; 653231437Sluigi 654231437Sluigistruct oce_mbx_ctx { 655231437Sluigi struct oce_mbx *mbx; 656231437Sluigi void (*cb) (void *ctx); 657231437Sluigi void *cb_ctx; 658231437Sluigi}; 659231437Sluigi 660231437Sluigistruct wq_config { 661231437Sluigi uint8_t wq_type; 662231437Sluigi uint16_t buf_size; 663231437Sluigi uint8_t pad[1]; 664231437Sluigi uint32_t q_len; 665231437Sluigi uint16_t pd_id; 666231437Sluigi uint16_t pci_fn_num; 667231437Sluigi uint32_t eqd; /* interrupt delay */ 668231437Sluigi uint32_t nbufs; 669231437Sluigi uint32_t nhdl; 670231437Sluigi}; 671231437Sluigi 672231437Sluigistruct oce_tx_queue_stats { 673231437Sluigi uint64_t tx_pkts; 674231437Sluigi uint64_t tx_bytes; 675231437Sluigi uint32_t tx_reqs; 676231437Sluigi uint32_t tx_stops; /* number of times TX Q was stopped */ 677231437Sluigi uint32_t tx_wrbs; 678231437Sluigi uint32_t tx_compl; 679231437Sluigi uint32_t tx_rate; 680231437Sluigi uint32_t ipv6_ext_hdr_tx_drop; 681231437Sluigi}; 682231437Sluigi 683231437Sluigistruct oce_wq { 684231437Sluigi OCE_LOCK tx_lock; 685231437Sluigi void *parent; 686231437Sluigi oce_ring_buffer_t *ring; 687231437Sluigi struct oce_cq *cq; 688231437Sluigi bus_dma_tag_t tag; 689231437Sluigi struct oce_packet_desc pckts[OCE_WQ_PACKET_ARRAY_SIZE]; 690252869Sdelphij uint32_t pkt_desc_tail; 691252869Sdelphij uint32_t pkt_desc_head; 692231437Sluigi uint32_t wqm_used; 693231437Sluigi boolean_t resched; 694231437Sluigi uint32_t wq_free; 695231437Sluigi uint32_t tx_deferd; 696231437Sluigi uint32_t pkt_drops; 697231437Sluigi qstate_t qstate; 698231437Sluigi uint16_t wq_id; 699231437Sluigi struct wq_config cfg; 700231437Sluigi int queue_index; 701231437Sluigi struct oce_tx_queue_stats tx_stats; 702231437Sluigi struct buf_ring *br; 703231437Sluigi struct task txtask; 704252869Sdelphij uint32_t db_offset; 705231437Sluigi}; 706231437Sluigi 707231437Sluigistruct rq_config { 708231437Sluigi uint32_t q_len; 709231437Sluigi uint32_t frag_size; 710231437Sluigi uint32_t mtu; 711231437Sluigi uint32_t if_id; 712231437Sluigi uint32_t is_rss_queue; 713231437Sluigi uint32_t eqd; 714231437Sluigi uint32_t nbufs; 715231437Sluigi}; 716231437Sluigi 717231437Sluigistruct oce_rx_queue_stats { 718231437Sluigi uint32_t rx_post_fail; 719231437Sluigi uint32_t rx_ucast_pkts; 720231437Sluigi uint32_t rx_compl; 721231437Sluigi uint64_t rx_bytes; 722231437Sluigi uint64_t rx_bytes_prev; 723231437Sluigi uint64_t rx_pkts; 724231437Sluigi uint32_t rx_rate; 725231437Sluigi uint32_t rx_mcast_pkts; 726231437Sluigi uint32_t rxcp_err; 727231437Sluigi uint32_t rx_frags; 728231437Sluigi uint32_t prev_rx_frags; 729231437Sluigi uint32_t rx_fps; 730231437Sluigi}; 731231437Sluigi 732231437Sluigi 733231437Sluigistruct oce_rq { 734231437Sluigi struct rq_config cfg; 735231437Sluigi uint32_t rq_id; 736231437Sluigi int queue_index; 737231437Sluigi uint32_t rss_cpuid; 738231437Sluigi void *parent; 739231437Sluigi oce_ring_buffer_t *ring; 740231437Sluigi struct oce_cq *cq; 741231437Sluigi void *pad1; 742231437Sluigi bus_dma_tag_t tag; 743231437Sluigi struct oce_packet_desc pckts[OCE_RQ_PACKET_ARRAY_SIZE]; 744231437Sluigi uint32_t packets_in; 745231437Sluigi uint32_t packets_out; 746231437Sluigi uint32_t pending; 747231437Sluigi#ifdef notdef 748231437Sluigi struct mbuf *head; 749231437Sluigi struct mbuf *tail; 750231437Sluigi int fragsleft; 751231437Sluigi#endif 752231437Sluigi qstate_t qstate; 753231437Sluigi OCE_LOCK rx_lock; 754231437Sluigi struct oce_rx_queue_stats rx_stats; 755231437Sluigi struct lro_ctrl lro; 756231437Sluigi int lro_pkts_queued; 757231437Sluigi 758231437Sluigi}; 759231437Sluigi 760231437Sluigistruct link_status { 761268046Sdelphij uint8_t phys_port_speed; 762268046Sdelphij uint8_t logical_link_status; 763231437Sluigi uint16_t qos_link_speed; 764231437Sluigi}; 765231437Sluigi 766231437Sluigi 767231437Sluigi 768231437Sluigi#define OCE_FLAGS_PCIX 0x00000001 769231437Sluigi#define OCE_FLAGS_PCIE 0x00000002 770231437Sluigi#define OCE_FLAGS_MSI_CAPABLE 0x00000004 771231437Sluigi#define OCE_FLAGS_MSIX_CAPABLE 0x00000008 772231437Sluigi#define OCE_FLAGS_USING_MSI 0x00000010 773231437Sluigi#define OCE_FLAGS_USING_MSIX 0x00000020 774231437Sluigi#define OCE_FLAGS_FUNCRESET_RQD 0x00000040 775231437Sluigi#define OCE_FLAGS_VIRTUAL_PORT 0x00000080 776231437Sluigi#define OCE_FLAGS_MBOX_ENDIAN_RQD 0x00000100 777231437Sluigi#define OCE_FLAGS_BE3 0x00000200 778231437Sluigi#define OCE_FLAGS_XE201 0x00000400 779231437Sluigi#define OCE_FLAGS_BE2 0x00000800 780252869Sdelphij#define OCE_FLAGS_SH 0x00001000 781231437Sluigi 782231437Sluigi#define OCE_DEV_BE2_CFG_BAR 1 783231437Sluigi#define OCE_DEV_CFG_BAR 0 784231437Sluigi#define OCE_PCI_CSR_BAR 2 785231437Sluigi#define OCE_PCI_DB_BAR 4 786231437Sluigi 787231437Sluigitypedef struct oce_softc { 788231437Sluigi device_t dev; 789231437Sluigi OCE_LOCK dev_lock; 790231437Sluigi 791231437Sluigi uint32_t flags; 792231437Sluigi 793231437Sluigi uint32_t pcie_link_speed; 794231437Sluigi uint32_t pcie_link_width; 795231437Sluigi 796231437Sluigi uint8_t fn; /* PCI function number */ 797231437Sluigi 798231437Sluigi struct resource *devcfg_res; 799231437Sluigi bus_space_tag_t devcfg_btag; 800231437Sluigi bus_space_handle_t devcfg_bhandle; 801231437Sluigi void *devcfg_vhandle; 802231437Sluigi 803231437Sluigi struct resource *csr_res; 804231437Sluigi bus_space_tag_t csr_btag; 805231437Sluigi bus_space_handle_t csr_bhandle; 806231437Sluigi void *csr_vhandle; 807231437Sluigi 808231437Sluigi struct resource *db_res; 809231437Sluigi bus_space_tag_t db_btag; 810231437Sluigi bus_space_handle_t db_bhandle; 811231437Sluigi void *db_vhandle; 812231437Sluigi 813231437Sluigi OCE_INTR_INFO intrs[OCE_MAX_EQ]; 814231437Sluigi int intr_count; 815231437Sluigi 816231437Sluigi struct ifnet *ifp; 817231437Sluigi 818231437Sluigi struct ifmedia media; 819231437Sluigi uint8_t link_status; 820231437Sluigi uint8_t link_speed; 821231437Sluigi uint8_t duplex; 822231437Sluigi uint32_t qos_link_speed; 823231437Sluigi uint32_t speed; 824231437Sluigi 825231437Sluigi char fw_version[32]; 826231437Sluigi struct mac_address_format macaddr; 827231437Sluigi 828231437Sluigi OCE_DMA_MEM bsmbx; 829231437Sluigi OCE_LOCK bmbx_lock; 830231437Sluigi 831231437Sluigi uint32_t config_number; 832231437Sluigi uint32_t asic_revision; 833231437Sluigi uint32_t port_id; 834231437Sluigi uint32_t function_mode; 835231437Sluigi uint32_t function_caps; 836231437Sluigi uint32_t max_tx_rings; 837231437Sluigi uint32_t max_rx_rings; 838231437Sluigi 839231437Sluigi struct oce_wq *wq[OCE_MAX_WQ]; /* TX work queues */ 840231437Sluigi struct oce_rq *rq[OCE_MAX_RQ]; /* RX work queues */ 841231437Sluigi struct oce_cq *cq[OCE_MAX_CQ]; /* Completion queues */ 842231437Sluigi struct oce_eq *eq[OCE_MAX_EQ]; /* Event queues */ 843231437Sluigi struct oce_mq *mq; /* Mailbox queue */ 844231437Sluigi 845231437Sluigi uint32_t neqs; 846231437Sluigi uint32_t ncqs; 847231437Sluigi uint32_t nrqs; 848231437Sluigi uint32_t nwqs; 849252869Sdelphij uint32_t nrssqs; 850231437Sluigi 851231437Sluigi uint32_t tx_ring_size; 852231437Sluigi uint32_t rx_ring_size; 853231437Sluigi uint32_t rq_frag_size; 854231437Sluigi 855231437Sluigi uint32_t if_id; /* interface ID */ 856231437Sluigi uint32_t nifs; /* number of adapter interfaces, 0 or 1 */ 857231437Sluigi uint32_t pmac_id; /* PMAC id */ 858231437Sluigi 859231437Sluigi uint32_t if_cap_flags; 860231437Sluigi 861231437Sluigi uint32_t flow_control; 862257187Sdelphij uint8_t promisc; 863247880Sdelphij 864247880Sdelphij struct oce_aic_obj aic_obj[OCE_MAX_EQ]; 865247880Sdelphij 866231437Sluigi /*Vlan Filtering related */ 867231437Sluigi eventhandler_tag vlan_attach; 868231437Sluigi eventhandler_tag vlan_detach; 869231437Sluigi uint16_t vlans_added; 870231437Sluigi uint8_t vlan_tag[MAX_VLANS]; 871231437Sluigi /*stats */ 872231437Sluigi OCE_DMA_MEM stats_mem; 873231437Sluigi struct oce_drv_stats oce_stats_info; 874231437Sluigi struct callout timer; 875231437Sluigi int8_t be3_native; 876257187Sdelphij uint8_t hw_error; 877247880Sdelphij uint16_t qnq_debug_event; 878247880Sdelphij uint16_t qnqid; 879259050Sdelphij uint32_t pvid; 880259050Sdelphij uint32_t max_vlans; 881231437Sluigi 882231437Sluigi} OCE_SOFTC, *POCE_SOFTC; 883231437Sluigi 884231437Sluigi 885231437Sluigi 886231437Sluigi/************************************************** 887231437Sluigi * BUS memory read/write macros 888231437Sluigi * BE3: accesses three BAR spaces (CFG, CSR, DB) 889231437Sluigi * Lancer: accesses one BAR space (CFG) 890231437Sluigi **************************************************/ 891252869Sdelphij#define OCE_READ_CSR_MPU(sc, space, o) \ 892252869Sdelphij ((IS_BE(sc)) ? (bus_space_read_4((sc)->space##_btag, \ 893252869Sdelphij (sc)->space##_bhandle,o)) \ 894252869Sdelphij : (bus_space_read_4((sc)->devcfg_btag, \ 895252869Sdelphij (sc)->devcfg_bhandle,o))) 896231437Sluigi#define OCE_READ_REG32(sc, space, o) \ 897252869Sdelphij ((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_4((sc)->space##_btag, \ 898252869Sdelphij (sc)->space##_bhandle,o)) \ 899252869Sdelphij : (bus_space_read_4((sc)->devcfg_btag, \ 900252869Sdelphij (sc)->devcfg_bhandle,o))) 901231437Sluigi#define OCE_READ_REG16(sc, space, o) \ 902252869Sdelphij ((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_2((sc)->space##_btag, \ 903252869Sdelphij (sc)->space##_bhandle,o)) \ 904252869Sdelphij : (bus_space_read_2((sc)->devcfg_btag, \ 905252869Sdelphij (sc)->devcfg_bhandle,o))) 906231437Sluigi#define OCE_READ_REG8(sc, space, o) \ 907252869Sdelphij ((IS_BE(sc) || IS_SH(sc)) ? (bus_space_read_1((sc)->space##_btag, \ 908252869Sdelphij (sc)->space##_bhandle,o)) \ 909252869Sdelphij : (bus_space_read_1((sc)->devcfg_btag, \ 910252869Sdelphij (sc)->devcfg_bhandle,o))) 911231437Sluigi 912252869Sdelphij#define OCE_WRITE_CSR_MPU(sc, space, o, v) \ 913231437Sluigi ((IS_BE(sc)) ? (bus_space_write_4((sc)->space##_btag, \ 914231437Sluigi (sc)->space##_bhandle,o,v)) \ 915252869Sdelphij : (bus_space_write_4((sc)->devcfg_btag, \ 916252869Sdelphij (sc)->devcfg_bhandle,o,v))) 917252869Sdelphij#define OCE_WRITE_REG32(sc, space, o, v) \ 918252869Sdelphij ((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_4((sc)->space##_btag, \ 919252869Sdelphij (sc)->space##_bhandle,o,v)) \ 920252869Sdelphij : (bus_space_write_4((sc)->devcfg_btag, \ 921252869Sdelphij (sc)->devcfg_bhandle,o,v))) 922231437Sluigi#define OCE_WRITE_REG16(sc, space, o, v) \ 923252869Sdelphij ((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_2((sc)->space##_btag, \ 924231437Sluigi (sc)->space##_bhandle,o,v)) \ 925252869Sdelphij : (bus_space_write_2((sc)->devcfg_btag, \ 926252869Sdelphij (sc)->devcfg_bhandle,o,v))) 927231437Sluigi#define OCE_WRITE_REG8(sc, space, o, v) \ 928252869Sdelphij ((IS_BE(sc) || IS_SH(sc)) ? (bus_space_write_1((sc)->space##_btag, \ 929231437Sluigi (sc)->space##_bhandle,o,v)) \ 930252869Sdelphij : (bus_space_write_1((sc)->devcfg_btag, \ 931252869Sdelphij (sc)->devcfg_bhandle,o,v))) 932231437Sluigi 933231437Sluigi 934231437Sluigi/*********************************************************** 935231437Sluigi * DMA memory functions 936231437Sluigi ***********************************************************/ 937231437Sluigi#define oce_dma_sync(d, f) bus_dmamap_sync((d)->tag, (d)->map, f) 938231437Sluigiint oce_dma_alloc(POCE_SOFTC sc, bus_size_t size, POCE_DMA_MEM dma, int flags); 939231437Sluigivoid oce_dma_free(POCE_SOFTC sc, POCE_DMA_MEM dma); 940231437Sluigivoid oce_dma_map_addr(void *arg, bus_dma_segment_t * segs, int nseg, int error); 941231437Sluigivoid oce_destroy_ring_buffer(POCE_SOFTC sc, oce_ring_buffer_t *ring); 942231437Sluigioce_ring_buffer_t *oce_create_ring_buffer(POCE_SOFTC sc, 943231437Sluigi uint32_t q_len, uint32_t num_entries); 944231437Sluigi/************************************************************ 945231437Sluigi * oce_hw_xxx functions 946231437Sluigi ************************************************************/ 947231437Sluigiint oce_clear_rx_buf(struct oce_rq *rq); 948231437Sluigiint oce_hw_pci_alloc(POCE_SOFTC sc); 949231437Sluigiint oce_hw_init(POCE_SOFTC sc); 950231437Sluigiint oce_hw_start(POCE_SOFTC sc); 951231437Sluigiint oce_create_nw_interface(POCE_SOFTC sc); 952231437Sluigiint oce_pci_soft_reset(POCE_SOFTC sc); 953231437Sluigiint oce_hw_update_multicast(POCE_SOFTC sc); 954231437Sluigivoid oce_delete_nw_interface(POCE_SOFTC sc); 955231437Sluigivoid oce_hw_shutdown(POCE_SOFTC sc); 956231437Sluigivoid oce_hw_intr_enable(POCE_SOFTC sc); 957231437Sluigivoid oce_hw_intr_disable(POCE_SOFTC sc); 958231437Sluigivoid oce_hw_pci_free(POCE_SOFTC sc); 959231437Sluigi 960231437Sluigi/*********************************************************** 961231437Sluigi * oce_queue_xxx functions 962231437Sluigi ***********************************************************/ 963231437Sluigiint oce_queue_init_all(POCE_SOFTC sc); 964231437Sluigiint oce_start_rq(struct oce_rq *rq); 965231437Sluigiint oce_start_wq(struct oce_wq *wq); 966231437Sluigiint oce_start_mq(struct oce_mq *mq); 967231437Sluigiint oce_start_rx(POCE_SOFTC sc); 968231437Sluigivoid oce_arm_eq(POCE_SOFTC sc, 969231437Sluigi int16_t qid, int npopped, uint32_t rearm, uint32_t clearint); 970231437Sluigivoid oce_queue_release_all(POCE_SOFTC sc); 971231437Sluigivoid oce_arm_cq(POCE_SOFTC sc, int16_t qid, int npopped, uint32_t rearm); 972231437Sluigivoid oce_drain_eq(struct oce_eq *eq); 973231437Sluigivoid oce_drain_mq_cq(void *arg); 974231437Sluigivoid oce_drain_rq_cq(struct oce_rq *rq); 975231437Sluigivoid oce_drain_wq_cq(struct oce_wq *wq); 976231437Sluigi 977231437Sluigiuint32_t oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list); 978231437Sluigi 979231437Sluigi/*********************************************************** 980231437Sluigi * cleanup functions 981231437Sluigi ***********************************************************/ 982231437Sluigivoid oce_stop_rx(POCE_SOFTC sc); 983231437Sluigivoid oce_intr_free(POCE_SOFTC sc); 984231437Sluigivoid oce_free_posted_rxbuf(struct oce_rq *rq); 985231879Sluigi#if defined(INET6) || defined(INET) 986231879Sluigivoid oce_free_lro(POCE_SOFTC sc); 987231879Sluigi#endif 988231437Sluigi 989231437Sluigi 990231437Sluigi/************************************************************ 991231437Sluigi * Mailbox functions 992231437Sluigi ************************************************************/ 993231437Sluigiint oce_fw_clean(POCE_SOFTC sc); 994231437Sluigiint oce_reset_fun(POCE_SOFTC sc); 995231437Sluigiint oce_mbox_init(POCE_SOFTC sc); 996231437Sluigiint oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec); 997231437Sluigiint oce_get_fw_version(POCE_SOFTC sc); 998231879Sluigiint oce_first_mcc_cmd(POCE_SOFTC sc); 999231879Sluigi 1000231437Sluigiint oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id, uint8_t perm, 1001231437Sluigi uint8_t type, struct mac_address_format *mac); 1002231437Sluigiint oce_get_fw_config(POCE_SOFTC sc); 1003231437Sluigiint oce_if_create(POCE_SOFTC sc, uint32_t cap_flags, uint32_t en_flags, 1004231437Sluigi uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id); 1005231437Sluigiint oce_if_del(POCE_SOFTC sc, uint32_t if_id); 1006231437Sluigiint oce_config_vlan(POCE_SOFTC sc, uint32_t if_id, 1007231437Sluigi struct normal_vlan *vtag_arr, uint8_t vtag_cnt, 1008231437Sluigi uint32_t untagged, uint32_t enable_promisc); 1009231437Sluigiint oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control); 1010231437Sluigiint oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss); 1011257187Sdelphijint oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable); 1012231437Sluigiint oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl); 1013231437Sluigiint oce_get_link_status(POCE_SOFTC sc, struct link_status *link); 1014231437Sluigiint oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem); 1015231437Sluigiint oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem); 1016231437Sluigiint oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem, 1017231437Sluigi uint32_t reset_stats); 1018231437Sluigiint oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem, 1019231437Sluigi uint32_t req_size, uint32_t reset_stats); 1020231437Sluigiint oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem); 1021231437Sluigiint oce_pass_through_mbox(POCE_SOFTC sc, POCE_DMA_MEM dma_mem, uint32_t req_size); 1022231437Sluigiint oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id); 1023231437Sluigiint oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr, 1024231437Sluigi uint32_t if_id, uint32_t *pmac_id); 1025231437Sluigiint oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num, 1026231437Sluigi uint32_t loopback_type, uint32_t pkt_size, uint32_t num_pkts, 1027231437Sluigi uint64_t pattern); 1028231437Sluigi 1029231437Sluigiint oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num, 1030231437Sluigi uint8_t loopback_type, uint8_t enable); 1031231437Sluigi 1032231437Sluigiint oce_mbox_check_native_mode(POCE_SOFTC sc); 1033231437Sluigiint oce_mbox_post(POCE_SOFTC sc, 1034231437Sluigi struct oce_mbx *mbx, struct oce_mbx_ctx *mbxctx); 1035231437Sluigiint oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode, 1036231437Sluigi POCE_DMA_MEM pdma_mem, uint32_t num_bytes); 1037231437Sluigiint oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size, 1038231437Sluigi uint32_t data_offset,POCE_DMA_MEM pdma_mem, 1039231437Sluigi uint32_t *written_data, uint32_t *additional_status); 1040231437Sluigi 1041231437Sluigiint oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc, 1042231437Sluigi uint32_t offset, uint32_t optype); 1043231437Sluigiint oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info); 1044231437Sluigiint oce_mbox_create_rq(struct oce_rq *rq); 1045231437Sluigiint oce_mbox_create_wq(struct oce_wq *wq); 1046231437Sluigiint oce_mbox_create_eq(struct oce_eq *eq); 1047231437Sluigiint oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, 1048231437Sluigi uint32_t is_eventable); 1049247880Sdelphijint oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num); 1050247880Sdelphijvoid oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd, 1051247880Sdelphij int num); 1052259050Sdelphijint oce_get_profile_config(POCE_SOFTC sc, uint32_t max_rss); 1053252869Sdelphijint oce_get_func_config(POCE_SOFTC sc); 1054231437Sluigivoid mbx_common_req_hdr_init(struct mbx_hdr *hdr, 1055231437Sluigi uint8_t dom, 1056231437Sluigi uint8_t port, 1057231437Sluigi uint8_t subsys, 1058231437Sluigi uint8_t opcode, 1059231437Sluigi uint32_t timeout, uint32_t pyld_len, 1060231437Sluigi uint8_t version); 1061231437Sluigi 1062231437Sluigi 1063231437Sluigiuint16_t oce_mq_handler(void *arg); 1064231437Sluigi 1065231437Sluigi/************************************************************ 1066231437Sluigi * Transmit functions 1067231437Sluigi ************************************************************/ 1068231437Sluigiuint16_t oce_wq_handler(void *arg); 1069231437Sluigivoid oce_start(struct ifnet *ifp); 1070231437Sluigivoid oce_tx_task(void *arg, int npending); 1071231437Sluigi 1072231437Sluigi/************************************************************ 1073231437Sluigi * Receive functions 1074231437Sluigi ************************************************************/ 1075231437Sluigiint oce_alloc_rx_bufs(struct oce_rq *rq, int count); 1076231437Sluigiuint16_t oce_rq_handler(void *arg); 1077231437Sluigi 1078231437Sluigi 1079231437Sluigi/* Sysctl functions */ 1080231437Sluigivoid oce_add_sysctls(POCE_SOFTC sc); 1081231437Sluigivoid oce_refresh_queue_stats(POCE_SOFTC sc); 1082231437Sluigiint oce_refresh_nic_stats(POCE_SOFTC sc); 1083231437Sluigiint oce_stats_init(POCE_SOFTC sc); 1084231437Sluigivoid oce_stats_free(POCE_SOFTC sc); 1085231437Sluigi 1086231437Sluigi/* Capabilities */ 1087231437Sluigi#define OCE_MODCAP_RSS 1 1088231437Sluigi#define OCE_MAX_RSP_HANDLED 64 1089231437Sluigiextern uint32_t oce_max_rsp_handled; /* max responses */ 1090231437Sluigi 1091231437Sluigi#define OCE_MAC_LOOPBACK 0x0 1092231437Sluigi#define OCE_PHY_LOOPBACK 0x1 1093231437Sluigi#define OCE_ONE_PORT_EXT_LOOPBACK 0x2 1094231437Sluigi#define OCE_NO_LOOPBACK 0xff 1095231437Sluigi 1096259050Sdelphij#undef IFM_40G_SR4 1097259050Sdelphij#define IFM_40G_SR4 28 1098259050Sdelphij 1099231437Sluigi#define atomic_inc_32(x) atomic_add_32(x, 1) 1100231437Sluigi#define atomic_dec_32(x) atomic_subtract_32(x, 1) 1101231437Sluigi 1102231437Sluigi#define LE_64(x) htole64(x) 1103231437Sluigi#define LE_32(x) htole32(x) 1104231437Sluigi#define LE_16(x) htole16(x) 1105252869Sdelphij#define HOST_64(x) le64toh(x) 1106252869Sdelphij#define HOST_32(x) le32toh(x) 1107252869Sdelphij#define HOST_16(x) le16toh(x) 1108231437Sluigi#define DW_SWAP(x, l) 1109231437Sluigi#define IS_ALIGNED(x,a) ((x % a) == 0) 1110231437Sluigi#define ADDR_HI(x) ((uint32_t)((uint64_t)(x) >> 32)) 1111231437Sluigi#define ADDR_LO(x) ((uint32_t)((uint64_t)(x) & 0xffffffff)); 1112231437Sluigi 1113231437Sluigi#define IF_LRO_ENABLED(sc) (((sc)->ifp->if_capenable & IFCAP_LRO) ? 1:0) 1114231437Sluigi#define IF_LSO_ENABLED(sc) (((sc)->ifp->if_capenable & IFCAP_TSO4) ? 1:0) 1115231437Sluigi#define IF_CSUM_ENABLED(sc) (((sc)->ifp->if_capenable & IFCAP_HWCSUM) ? 1:0) 1116231437Sluigi 1117231437Sluigi#define OCE_LOG2(x) (oce_highbit(x)) 1118231437Sluigistatic inline uint32_t oce_highbit(uint32_t x) 1119231437Sluigi{ 1120231437Sluigi int i; 1121231437Sluigi int c; 1122231437Sluigi int b; 1123231437Sluigi 1124231437Sluigi c = 0; 1125231437Sluigi b = 0; 1126231437Sluigi 1127231437Sluigi for (i = 0; i < 32; i++) { 1128231437Sluigi if ((1 << i) & x) { 1129231437Sluigi c++; 1130231437Sluigi b = i; 1131231437Sluigi } 1132231437Sluigi } 1133231437Sluigi 1134231437Sluigi if (c == 1) 1135231437Sluigi return b; 1136231437Sluigi 1137231437Sluigi return 0; 1138231437Sluigi} 1139231437Sluigi 1140252869Sdelphijstatic inline int MPU_EP_SEMAPHORE(POCE_SOFTC sc) 1141252869Sdelphij{ 1142252869Sdelphij if (IS_BE(sc)) 1143252869Sdelphij return MPU_EP_SEMAPHORE_BE3; 1144252869Sdelphij else if (IS_SH(sc)) 1145252869Sdelphij return MPU_EP_SEMAPHORE_SH; 1146252869Sdelphij else 1147252869Sdelphij return MPU_EP_SEMAPHORE_XE201; 1148252869Sdelphij} 1149252869Sdelphij 1150247880Sdelphij#define TRANSCEIVER_DATA_NUM_ELE 64 1151247880Sdelphij#define TRANSCEIVER_DATA_SIZE 256 1152247880Sdelphij#define TRANSCEIVER_A0_SIZE 128 1153247880Sdelphij#define TRANSCEIVER_A2_SIZE 128 1154247880Sdelphij#define PAGE_NUM_A0 0xa0 1155247880Sdelphij#define PAGE_NUM_A2 0xa2 1156247880Sdelphij#define IS_QNQ_OR_UMC(sc) ((sc->pvid && (sc->function_mode & FNM_UMC_MODE ))\ 1157247880Sdelphij || (sc->qnqid && (sc->function_mode & FNM_FLEX10_MODE))) 1158247880Sdelphij 1159