emulex_oce: Upgrade to FreeBSD 12.

This commit is contained in:
Augustin Cavalier
2018-12-27 16:55:35 -05:00
parent 2aaa3af64d
commit 522d143920
9 changed files with 2358 additions and 610 deletions
@@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2013 Emulex
* All rights reserved.
*
@@ -36,7 +38,7 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_hw.c 333813 2018-05-18 20:13:34Z mmacy $ */
#include "oce_if.h"
@@ -96,7 +98,7 @@ oce_hw_init(POCE_SOFTC sc)
rc = oce_POST(sc);
if (rc)
return rc;
/* create the bootstrap mailbox */
rc = oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->bsmbx, 0);
if (rc) {
@@ -107,7 +109,7 @@ oce_hw_init(POCE_SOFTC sc)
rc = oce_reset_fun(sc);
if (rc)
goto error;
rc = oce_mbox_init(sc);
if (rc)
@@ -129,14 +131,14 @@ oce_hw_init(POCE_SOFTC sc)
&sc->macaddr);
if (rc)
goto error;
if ((IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) || IS_SH(sc)) {
rc = oce_mbox_check_native_mode(sc);
if (rc)
goto error;
} else
sc->be3_native = 0;
return rc;
error:
@@ -209,7 +211,7 @@ void oce_get_pci_capabilities(POCE_SOFTC sc)
#endif
if (pci_find_extcap(sc->dev, PCIY_PCIX, &val) == 0) {
if (val != 0)
if (val != 0)
sc->flags |= OCE_FLAGS_PCIX;
}
@@ -260,10 +262,10 @@ oce_hw_pci_alloc(POCE_SOFTC sc)
pci_cfg_barnum = OCE_DEV_BE2_CFG_BAR;
else
pci_cfg_barnum = OCE_DEV_CFG_BAR;
rr = PCIR_BAR(pci_cfg_barnum);
if (IS_BE(sc) || IS_SH(sc))
if (IS_BE(sc) || IS_SH(sc))
sc->devcfg_res = bus_alloc_resource_any(sc->dev,
SYS_RES_MEMORY, &rr,
RF_ACTIVE|RF_SHAREABLE);
@@ -286,7 +288,7 @@ oce_hw_pci_alloc(POCE_SOFTC sc)
if (intf.bits.sli_valid != OCE_INTF_VALID_SIG)
goto error;
if (intf.bits.sli_rev != OCE_INTF_SLI_REV4) {
device_printf(sc->dev, "Adapter doesnt support SLI4\n");
goto error;
@@ -312,7 +314,7 @@ oce_hw_pci_alloc(POCE_SOFTC sc)
sc->csr_btag = rman_get_bustag(sc->csr_res);
sc->csr_bhandle = rman_get_bushandle(sc->csr_res);
sc->csr_vhandle = rman_get_virtual(sc->csr_res);
/* set up DB doorbell region */
rr = PCIR_BAR(OCE_PCI_DB_BAR);
sc->db_res = bus_alloc_resource_any(sc->dev,
@@ -326,7 +328,7 @@ oce_hw_pci_alloc(POCE_SOFTC sc)
return 0;
error:
error:
oce_hw_pci_free(sc);
return ENXIO;
}
@@ -393,6 +395,11 @@ oce_create_nw_interface(POCE_SOFTC sc)
if (IS_SH(sc) || IS_XE201(sc))
capab_flags |= MBX_RX_IFACE_FLAGS_MULTICAST;
if (sc->enable_hwlro) {
capab_flags |= MBX_RX_IFACE_FLAGS_LRO;
capab_en_flags |= MBX_RX_IFACE_FLAGS_LRO;
}
/* enable capabilities controlled via driver startup parameters */
if (is_rss_enabled(sc))
capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;
@@ -475,9 +482,9 @@ oce_hw_start(POCE_SOFTC sc)
int rc = 0;
rc = oce_get_link_status(sc, &link);
if (rc)
if (rc)
return 1;
if (link.logical_link_status == NTWK_LOGICAL_LINK_UP) {
sc->link_status = NTWK_LOGICAL_LINK_UP;
if_link_state_change(sc->ifp, LINK_STATE_UP);
@@ -490,9 +497,9 @@ oce_hw_start(POCE_SOFTC sc)
sc->qos_link_speed = (uint32_t )link.qos_link_speed * 10;
rc = oce_start_mq(sc->mq);
/* we need to get MCC aync events. So enable intrs and arm
first EQ, Other EQs will be armed after interface is UP
first EQ, Other EQs will be armed after interface is UP
*/
oce_hw_intr_enable(sc);
oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
@@ -530,7 +537,7 @@ void
oce_hw_intr_disable(POCE_SOFTC sc)
{
uint32_t reg;
reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL);
reg &= ~HOSTINTR_MASK;
OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg);
@@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2013 Emulex
* All rights reserved.
*
@@ -36,7 +38,7 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_hw.h 326022 2017-11-20 19:36:21Z pfg $ */
#include <sys/types.h>
@@ -111,6 +113,9 @@
#define PD_MPU_MBOX_DB 0x0160
#define PD_MQ_DB 0x0140
#define DB_OFFSET 0xc0
#define DB_LRO_RQ_ID_MASK 0x7FF
/* EQE completion types */
#define EQ_MINOR_CODE_COMPLETION 0x00
#define EQ_MINOR_CODE_OTHER 0x01
@@ -180,6 +185,7 @@
#define ASYNC_EVENT_GRP5 0x5
#define ASYNC_EVENT_CODE_DEBUG 0x6
#define ASYNC_EVENT_PVID_STATE 0x3
#define ASYNC_EVENT_OS2BMC 0x5
#define ASYNC_EVENT_DEBUG_QNQ 0x1
#define ASYNC_EVENT_CODE_SLIPORT 0x11
#define VLAN_VID_MASK 0x0FFF
@@ -722,6 +728,34 @@ struct oce_async_cqe_link_state {
} u0;
};
/* OS2BMC async event */
struct oce_async_evt_grp5_os2bmc {
union {
struct {
uint32_t lrn_enable:1;
uint32_t lrn_disable:1;
uint32_t mgmt_enable:1;
uint32_t mgmt_disable:1;
uint32_t rsvd0:12;
uint32_t vlan_tag:16;
uint32_t arp_filter:1;
uint32_t dhcp_client_filt:1;
uint32_t dhcp_server_filt:1;
uint32_t net_bios_filt:1;
uint32_t rsvd1:3;
uint32_t bcast_filt:1;
uint32_t ipv6_nbr_filt:1;
uint32_t ipv6_ra_filt:1;
uint32_t ipv6_ras_filt:1;
uint32_t rsvd2[4];
uint32_t mcast_filt:1;
uint32_t rsvd3:16;
uint32_t evt_tag;
uint32_t dword3;
} s;
uint32_t dword[4];
} u;
};
/* PVID aync event */
struct oce_async_event_grp5_pvid_state {
@@ -1396,7 +1430,7 @@ typedef union oce_cq_ctx_u {
uint32_t dw5rsvd3:1;
uint32_t eventable:1;
/* dw6 */
uint32_t eq_id:8;
uint32_t eq_id:16;
uint32_t dw6rsvd1:15;
uint32_t armed:1;
/* dw7 */
@@ -2403,8 +2437,8 @@ struct oce_nic_hdr_wqe {
uint32_t tcpcs:1;
uint32_t udpcs:1;
uint32_t ipcs:1;
uint32_t rsvd3:1;
uint32_t rsvd2:1;
uint32_t mgmt:1;
uint32_t lso6:1;
uint32_t forward:1;
uint32_t crc:1;
uint32_t event:1;
@@ -2426,8 +2460,8 @@ struct oce_nic_hdr_wqe {
uint32_t event:1;
uint32_t crc:1;
uint32_t forward:1;
uint32_t rsvd2:1;
uint32_t rsvd3:1;
uint32_t lso6:1;
uint32_t mgmt:1;
uint32_t ipcs:1;
uint32_t udpcs:1;
uint32_t tcpcs:1;
@@ -3010,6 +3044,53 @@ struct oce_rxf_stats_v0 {
uint32_t rsvd1[6];
};
struct oce_port_rxf_stats_v2 {
uint32_t rsvd0[10];
uint32_t roce_bytes_received_lsd;
uint32_t roce_bytes_received_msd;
uint32_t rsvd1[5];
uint32_t roce_frames_received;
uint32_t rx_crc_errors;
uint32_t rx_alignment_symbol_errors;
uint32_t rx_pause_frames;
uint32_t rx_priority_pause_frames;
uint32_t rx_control_frames;
uint32_t rx_in_range_errors;
uint32_t rx_out_range_errors;
uint32_t rx_frame_too_long;
uint32_t rx_address_match_errors;
uint32_t rx_dropped_too_small;
uint32_t rx_dropped_too_short;
uint32_t rx_dropped_header_too_small;
uint32_t rx_dropped_tcp_length;
uint32_t rx_dropped_runt;
uint32_t rsvd2[10];
uint32_t rx_ip_checksum_errs;
uint32_t rx_tcp_checksum_errs;
uint32_t rx_udp_checksum_errs;
uint32_t rsvd3[7];
uint32_t rx_switched_unicast_packets;
uint32_t rx_switched_multicast_packets;
uint32_t rx_switched_broadcast_packets;
uint32_t rsvd4[3];
uint32_t tx_pauseframes;
uint32_t tx_priority_pauseframes;
uint32_t tx_controlframes;
uint32_t rsvd5[10];
uint32_t rxpp_fifo_overflow_drop;
uint32_t rx_input_fifo_overflow_drop;
uint32_t pmem_fifo_overflow_drop;
uint32_t jabber_events;
uint32_t rsvd6[3];
uint32_t rx_drops_payload_size;
uint32_t rx_drops_clipped_header;
uint32_t rx_drops_crc;
uint32_t roce_drops_payload_len;
uint32_t roce_drops_crc;
uint32_t rsvd7[19];
};
struct oce_port_rxf_stats_v1 {
uint32_t rsvd0[12];
uint32_t rx_crc_errors;
@@ -3046,6 +3127,20 @@ struct oce_port_rxf_stats_v1 {
uint32_t rsvd5[3];
};
struct oce_rxf_stats_v2 {
struct oce_port_rxf_stats_v2 port[4];
uint32_t rsvd0[2];
uint32_t rx_drops_no_pbuf;
uint32_t rx_drops_no_txpb;
uint32_t rx_drops_no_erx_descr;
uint32_t rx_drops_no_tpre_descr;
uint32_t rsvd1[6];
uint32_t rx_drops_too_many_frags;
uint32_t rx_drops_invalid_ring;
uint32_t forwarded_packets;
uint32_t rx_drops_mtu;
uint32_t rsvd2[35];
};
struct oce_rxf_stats_v1 {
struct oce_port_rxf_stats_v1 port[4];
@@ -3062,6 +3157,11 @@ struct oce_rxf_stats_v1 {
uint32_t rsvd2[14];
};
struct oce_erx_stats_v2 {
uint32_t rx_drops_no_fragments[136];
uint32_t rsvd[3];
};
struct oce_erx_stats_v1 {
uint32_t rx_drops_no_fragments[68];
uint32_t rsvd[4];
@@ -3078,6 +3178,15 @@ struct oce_pmem_stats {
uint32_t rsvd[5];
};
struct oce_hw_stats_v2 {
struct oce_rxf_stats_v2 rxf;
uint32_t rsvd0[OCE_TXP_SW_SZ];
struct oce_erx_stats_v2 erx;
struct oce_pmem_stats pmem;
uint32_t rsvd1[18];
};
struct oce_hw_stats_v1 {
struct oce_rxf_stats_v1 rxf;
uint32_t rsvd0[OCE_TXP_SW_SZ];
@@ -3093,32 +3202,22 @@ struct oce_hw_stats_v0 {
struct oce_pmem_stats pmem;
};
struct mbx_get_nic_stats_v0 {
struct mbx_hdr hdr;
union {
struct {
uint32_t rsvd0;
} req;
union {
struct oce_hw_stats_v0 stats;
} rsp;
} params;
};
struct mbx_get_nic_stats {
struct mbx_hdr hdr;
union {
struct {
uint32_t rsvd0;
} req;
struct {
struct oce_hw_stats_v1 stats;
} rsp;
} params;
};
#define MBX_GET_NIC_STATS(version) \
struct mbx_get_nic_stats_v##version { \
struct mbx_hdr hdr; \
union { \
struct { \
uint32_t rsvd0; \
} req; \
union { \
struct oce_hw_stats_v##version stats; \
} rsp; \
} params; \
}
MBX_GET_NIC_STATS(0);
MBX_GET_NIC_STATS(1);
MBX_GET_NIC_STATS(2);
/* [18(0x12)] NIC_GET_PPORT_STATS */
struct pport_stats {
@@ -3728,3 +3827,373 @@ enum OCE_QUEUE_RX_STATS {
QUEUE_RX_BUFFER_ERRORS = 8,
QUEUE_RX_N_WORDS = 10
};
/* HW LRO structures */
struct mbx_nic_query_lro_capabilities {
struct mbx_hdr hdr;
union {
struct {
uint32_t rsvd[6];
} req;
struct {
#ifdef _BIG_ENDIAN
uint32_t lro_flags;
uint16_t lro_rq_cnt;
uint16_t plro_max_offload;
uint32_t rsvd[4];
#else
uint32_t lro_flags;
uint16_t plro_max_offload;
uint16_t lro_rq_cnt;
uint32_t rsvd[4];
#endif
} rsp;
} params;
};
struct mbx_nic_set_iface_lro_config {
struct mbx_hdr hdr;
union {
struct {
#ifdef _BIG_ENDIAN
uint32_t lro_flags;
uint32_t iface_id;
uint32_t max_clsc_byte_cnt;
uint32_t max_clsc_seg_cnt;
uint32_t max_clsc_usec_delay;
uint32_t min_clsc_frame_byte_cnt;
uint32_t rsvd[2];
#else
uint32_t lro_flags;
uint32_t iface_id;
uint32_t max_clsc_byte_cnt;
uint32_t max_clsc_seg_cnt;
uint32_t max_clsc_usec_delay;
uint32_t min_clsc_frame_byte_cnt;
uint32_t rsvd[2];
#endif
} req;
struct {
#ifdef _BIG_ENDIAN
uint32_t lro_flags;
uint32_t rsvd[7];
#else
uint32_t lro_flags;
uint32_t rsvd[7];
#endif
} rsp;
} params;
};
struct mbx_create_nic_rq_v2 {
struct mbx_hdr hdr;
union {
struct {
#ifdef _BIG_ENDIAN
uint8_t num_pages;
uint8_t frag_size;
uint16_t cq_id;
uint32_t if_id;
uint16_t page_size;
uint16_t max_frame_size;
uint16_t rsvd;
uint16_t pd_id;
uint16_t rsvd1;
uint16_t rq_flags;
uint16_t hds_fixed_offset;
uint8_t hds_start;
uint8_t hds_frag;
uint16_t hds_backfill_size;
uint16_t hds_frag_size;
uint32_t rbq_id;
uint32_t rsvd2[8];
struct phys_addr pages[2];
#else
uint16_t cq_id;
uint8_t frag_size;
uint8_t num_pages;
uint32_t if_id;
uint16_t max_frame_size;
uint16_t page_size;
uint16_t pd_id;
uint16_t rsvd;
uint16_t rq_flags;
uint16_t rsvd1;
uint8_t hds_frag;
uint8_t hds_start;
uint16_t hds_fixed_offset;
uint16_t hds_frag_size;
uint16_t hds_backfill_size;
uint32_t rbq_id;
uint32_t rsvd2[8];
struct phys_addr pages[2];
#endif
} req;
struct {
#ifdef _BIG_ENDIAN
uint8_t rsvd0;
uint8_t rss_cpuid;
uint16_t rq_id;
uint8_t db_format;
uint8_t db_reg_set;
uint16_t rsvd1;
uint32_t db_offset;
uint32_t rsvd2;
uint16_t rsvd3;
uint16_t rq_flags;
#else
uint16_t rq_id;
uint8_t rss_cpuid;
uint8_t rsvd0;
uint16_t rsvd1;
uint8_t db_reg_set;
uint8_t db_format;
uint32_t db_offset;
uint32_t rsvd2;
uint16_t rq_flags;
uint16_t rsvd3;
#endif
} rsp;
} params;
};
struct mbx_delete_nic_rq_v1 {
struct mbx_hdr hdr;
union {
struct {
#ifdef _BIG_ENDIAN
uint16_t bypass_flush;
uint16_t rq_id;
uint16_t rsvd;
uint16_t rq_flags;
#else
uint16_t rq_id;
uint16_t bypass_flush;
uint16_t rq_flags;
uint16_t rsvd;
#endif
} req;
struct {
uint32_t rsvd[2];
} rsp;
} params;
};
struct nic_hwlro_singleton_cqe {
#ifdef _BIG_ENDIAN
/* dw 0 */
uint32_t ip_opt:1;
uint32_t vtp:1;
uint32_t pkt_size:14;
uint32_t vlan_tag:16;
/* dw 1 */
uint32_t num_frags:3;
uint32_t rsvd1:3;
uint32_t frag_index:10;
uint32_t rsvd:8;
uint32_t ipv6_frame:1;
uint32_t l4_cksum_pass:1;
uint32_t ip_cksum_pass:1;
uint32_t udpframe:1;
uint32_t tcpframe:1;
uint32_t ipframe:1;
uint32_t rss_hp:1;
uint32_t error:1;
/* dw 2 */
uint32_t valid:1;
uint32_t cqe_type:2;
uint32_t debug:7;
uint32_t rsvd4:6;
uint32_t data_offset:8;
uint32_t rsvd3:3;
uint32_t rss_bank:1;
uint32_t qnq:1;
uint32_t rsvd2:3;
/* dw 3 */
uint32_t rss_hash_value;
#else
/* dw 0 */
uint32_t vlan_tag:16;
uint32_t pkt_size:14;
uint32_t vtp:1;
uint32_t ip_opt:1;
/* dw 1 */
uint32_t error:1;
uint32_t rss_hp:1;
uint32_t ipframe:1;
uint32_t tcpframe:1;
uint32_t udpframe:1;
uint32_t ip_cksum_pass:1;
uint32_t l4_cksum_pass:1;
uint32_t ipv6_frame:1;
uint32_t rsvd:8;
uint32_t frag_index:10;
uint32_t rsvd1:3;
uint32_t num_frags:3;
/* dw 2 */
uint32_t rsvd2:3;
uint32_t qnq:1;
uint32_t rss_bank:1;
uint32_t rsvd3:3;
uint32_t data_offset:8;
uint32_t rsvd4:6;
uint32_t debug:7;
uint32_t cqe_type:2;
uint32_t valid:1;
/* dw 3 */
uint32_t rss_hash_value;
#endif
};
struct nic_hwlro_cqe_part1 {
#ifdef _BIG_ENDIAN
/* dw 0 */
uint32_t tcp_timestamp_val;
/* dw 1 */
uint32_t tcp_timestamp_ecr;
/* dw 2 */
uint32_t valid:1;
uint32_t cqe_type:2;
uint32_t rsvd3:7;
uint32_t rss_policy:4;
uint32_t rsvd2:2;
uint32_t data_offset:8;
uint32_t rsvd1:1;
uint32_t lro_desc:1;
uint32_t lro_timer_pop:1;
uint32_t rss_bank:1;
uint32_t qnq:1;
uint32_t rsvd:2;
uint32_t rss_flush:1;
/* dw 3 */
uint32_t rss_hash_value;
#else
/* dw 0 */
uint32_t tcp_timestamp_val;
/* dw 1 */
uint32_t tcp_timestamp_ecr;
/* dw 2 */
uint32_t rss_flush:1;
uint32_t rsvd:2;
uint32_t qnq:1;
uint32_t rss_bank:1;
uint32_t lro_timer_pop:1;
uint32_t lro_desc:1;
uint32_t rsvd1:1;
uint32_t data_offset:8;
uint32_t rsvd2:2;
uint32_t rss_policy:4;
uint32_t rsvd3:7;
uint32_t cqe_type:2;
uint32_t valid:1;
/* dw 3 */
uint32_t rss_hash_value;
#endif
};
struct nic_hwlro_cqe_part2 {
#ifdef _BIG_ENDIAN
/* dw 0 */
uint32_t ip_opt:1;
uint32_t vtp:1;
uint32_t pkt_size:14;
uint32_t vlan_tag:16;
/* dw 1 */
uint32_t tcp_window:16;
uint32_t coalesced_size:16;
/* dw 2 */
uint32_t valid:1;
uint32_t cqe_type:2;
uint32_t rsvd:2;
uint32_t push:1;
uint32_t ts_opt:1;
uint32_t threshold:1;
uint32_t seg_cnt:8;
uint32_t frame_lifespan:8;
uint32_t ipv6_frame:1;
uint32_t l4_cksum_pass:1;
uint32_t ip_cksum_pass:1;
uint32_t udpframe:1;
uint32_t tcpframe:1;
uint32_t ipframe:1;
uint32_t rss_hp:1;
uint32_t error:1;
/* dw 3 */
uint32_t tcp_ack_num;
#else
/* dw 0 */
uint32_t vlan_tag:16;
uint32_t pkt_size:14;
uint32_t vtp:1;
uint32_t ip_opt:1;
/* dw 1 */
uint32_t coalesced_size:16;
uint32_t tcp_window:16;
/* dw 2 */
uint32_t error:1;
uint32_t rss_hp:1;
uint32_t ipframe:1;
uint32_t tcpframe:1;
uint32_t udpframe:1;
uint32_t ip_cksum_pass:1;
uint32_t l4_cksum_pass:1;
uint32_t ipv6_frame:1;
uint32_t frame_lifespan:8;
uint32_t seg_cnt:8;
uint32_t threshold:1;
uint32_t ts_opt:1;
uint32_t push:1;
uint32_t rsvd:2;
uint32_t cqe_type:2;
uint32_t valid:1;
/* dw 3 */
uint32_t tcp_ack_num;
#endif
};
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2013 Emulex
* All rights reserved.
*
@@ -36,7 +38,7 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_if.h 333146 2018-05-01 17:39:20Z jpaetzel $ */
#include <sys/param.h>
#include <sys/endian.h>
@@ -45,7 +47,6 @@
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/buf_ring.h>
#include <sys/mbuf.h>
#include <sys/rman.h>
#include <sys/socket.h>
@@ -82,8 +83,6 @@
#ifndef __HAIKU__
#include <netinet6/in6_var.h>
#include <netinet6/ip6_mroute.h>
#else
#include <netinet6/in6.h>
#endif
#include <netinet/udp.h>
@@ -92,13 +91,14 @@
#include <netinet/sctp.h>
#include <netinet/tcp_lro.h>
#endif
#include <netinet/icmp6.h>
#include <machine/bus.h>
#include "oce_hw.h"
/* OCE device driver module component revision informaiton */
#define COMPONENT_REVISION "10.0.664.0"
#define COMPONENT_REVISION "11.0.50.0"
/* OCE devices supported by this driver */
#define PCI_VENDOR_EMULEX 0x10df /* Emulex */
@@ -149,7 +149,6 @@ extern int mp_ncpus; /* system's total active cpu cores */
#define OCE_DEFAULT_WQ_EQD 16
#define OCE_MAX_PACKET_Q 16
#define OCE_RQ_BUF_SIZE 2048
#define OCE_LSO_MAX_SIZE (64 * 1024)
#define LONG_TIMEOUT 30
#define OCE_MAX_JUMBO_FRAME_SIZE 9018
@@ -157,11 +156,15 @@ extern int mp_ncpus; /* system's total active cpu cores */
ETHER_VLAN_ENCAP_LEN - \
ETHER_HDR_LEN)
#define OCE_RDMA_VECTORS 2
#define OCE_MAX_TX_ELEMENTS 29
#define OCE_MAX_TX_DESC 1024
#define OCE_MAX_TX_SIZE 65535
#define OCE_MAX_TSO_SIZE (65535 - ETHER_HDR_LEN)
#define OCE_MAX_RX_SIZE 4096
#define OCE_MAX_RQ_POSTS 255
#define OCE_HWLRO_MAX_RQ_POSTS 64
#define OCE_DEFAULT_PROMISCUOUS 0
@@ -510,7 +513,7 @@ struct oce_drv_stats {
#define INTR_RATE_LWM 10000
#define OCE_MAX_EQD 128u
#define OCE_MIN_EQD 50u
#define OCE_MIN_EQD 0u
struct oce_set_eqd {
uint32_t eq_id;
@@ -525,7 +528,8 @@ struct oce_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
uint32_t cur_eqd; /* in usecs */
uint32_t et_eqd; /* configured value when aic is off */
uint64_t _ticks;
uint64_t intr_prev;
uint64_t prev_rxpkts;
uint64_t prev_txreqs;
};
#define MAX_LOCK_DESC_LEN 32
@@ -616,7 +620,8 @@ struct oce_eq {
enum cq_len {
CQ_LEN_256 = 256,
CQ_LEN_512 = 512,
CQ_LEN_1024 = 1024
CQ_LEN_1024 = 1024,
CQ_LEN_2048 = 2048
};
struct cq_config {
@@ -692,6 +697,7 @@ struct oce_tx_queue_stats {
struct oce_wq {
OCE_LOCK tx_lock;
OCE_LOCK tx_compl_lock;
void *parent;
oce_ring_buffer_t *ring;
struct oce_cq *cq;
@@ -737,6 +743,7 @@ struct oce_rx_queue_stats {
uint32_t rx_frags;
uint32_t prev_rx_frags;
uint32_t rx_fps;
uint32_t rx_drops_no_frags; /* HW has no fetched frags */
};
@@ -751,8 +758,6 @@ struct oce_rq {
void *pad1;
bus_dma_tag_t tag;
struct oce_packet_desc pckts[OCE_RQ_PACKET_ARRAY_SIZE];
uint32_t packets_in;
uint32_t packets_out;
uint32_t pending;
#ifdef notdef
struct mbuf *head;
@@ -766,6 +771,8 @@ struct oce_rq {
struct lro_ctrl lro;
#endif
int lro_pkts_queued;
int islro;
struct nic_hwlro_cqe_part1 *cqe_firstpart;
};
@@ -790,6 +797,7 @@ struct link_status {
#define OCE_FLAGS_XE201 0x00000400
#define OCE_FLAGS_BE2 0x00000800
#define OCE_FLAGS_SH 0x00001000
#define OCE_FLAGS_OS2BMC 0x00002000
#define OCE_DEV_BE2_CFG_BAR 1
#define OCE_DEV_CFG_BAR 0
@@ -824,6 +832,7 @@ typedef struct oce_softc {
OCE_INTR_INFO intrs[OCE_MAX_EQ];
int intr_count;
int roce_intr_count;
struct ifnet *ifp;
@@ -833,6 +842,7 @@ typedef struct oce_softc {
uint8_t duplex;
uint32_t qos_link_speed;
uint32_t speed;
uint32_t enable_hwlro;
char fw_version[32];
struct mac_address_format macaddr;
@@ -890,9 +900,15 @@ typedef struct oce_softc {
uint16_t qnqid;
uint32_t pvid;
uint32_t max_vlans;
uint32_t bmc_filt_mask;
void *rdma_context;
uint32_t rdma_flags;
struct oce_softc *next;
} OCE_SOFTC, *POCE_SOFTC;
#define OCE_RDMA_FLAG_SUPPORTED 0x00000001
/**************************************************
@@ -942,7 +958,7 @@ typedef struct oce_softc {
: (bus_space_write_1((sc)->devcfg_btag, \
(sc)->devcfg_bhandle,o,v)))
void oce_rx_flush_lro(struct oce_rq *rq);
/***********************************************************
* DMA memory functions
***********************************************************/
@@ -992,6 +1008,9 @@ uint32_t oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list);
* cleanup functions
***********************************************************/
void oce_stop_rx(POCE_SOFTC sc);
void oce_discard_rx_comp(struct oce_rq *rq, int num_frags);
void oce_rx_cq_clean(struct oce_rq *rq);
void oce_rx_cq_clean_hwlro(struct oce_rq *rq);
void oce_intr_free(POCE_SOFTC sc);
void oce_free_posted_rxbuf(struct oce_rq *rq);
#if defined(INET6) || defined(INET)
@@ -1003,6 +1022,7 @@ void oce_free_lro(POCE_SOFTC sc);
* Mailbox functions
************************************************************/
int oce_fw_clean(POCE_SOFTC sc);
int oce_wait_ready(POCE_SOFTC sc);
int oce_reset_fun(POCE_SOFTC sc);
int oce_mbox_init(POCE_SOFTC sc);
int oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec);
@@ -1024,7 +1044,8 @@ int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable);
int oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl);
int oce_get_link_status(POCE_SOFTC sc, struct link_status *link);
int oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
int oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
int oce_mbox_get_nic_stats_v1(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
int oce_mbox_get_nic_stats_v2(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
int oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
uint32_t reset_stats);
int oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
@@ -1095,10 +1116,16 @@ int oce_refresh_nic_stats(POCE_SOFTC sc);
int oce_stats_init(POCE_SOFTC sc);
void oce_stats_free(POCE_SOFTC sc);
/* hw lro functions */
int oce_mbox_nic_query_lro_capabilities(POCE_SOFTC sc, uint32_t *lro_rq_cnt, uint32_t *lro_flags);
int oce_mbox_nic_set_iface_lro_config(POCE_SOFTC sc, int enable);
int oce_mbox_create_rq_v2(struct oce_rq *rq);
/* Capabilities */
#define OCE_MODCAP_RSS 1
#define OCE_MAX_RSP_HANDLED 64
extern uint32_t oce_max_rsp_handled; /* max responses */
extern uint32_t oce_rq_buf_size;
#define OCE_MAC_LOOPBACK 0x0
#define OCE_PHY_LOOPBACK 0x1
@@ -1168,3 +1195,80 @@ static inline int MPU_EP_SEMAPHORE(POCE_SOFTC sc)
#define IS_QNQ_OR_UMC(sc) ((sc->pvid && (sc->function_mode & FNM_UMC_MODE ))\
|| (sc->qnqid && (sc->function_mode & FNM_FLEX10_MODE)))
struct oce_rdma_info;
extern struct oce_rdma_if *oce_rdma_if;
/* OS2BMC related */
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_PORT 67
#define NET_BIOS_PORT1 137
#define NET_BIOS_PORT2 138
#define DHCPV6_RAS_PORT 547
#define BMC_FILT_BROADCAST_ARP ((uint32_t)(1))
#define BMC_FILT_BROADCAST_DHCP_CLIENT ((uint32_t)(1 << 1))
#define BMC_FILT_BROADCAST_DHCP_SERVER ((uint32_t)(1 << 2))
#define BMC_FILT_BROADCAST_NET_BIOS ((uint32_t)(1 << 3))
#define BMC_FILT_BROADCAST ((uint32_t)(1 << 4))
#define BMC_FILT_MULTICAST_IPV6_NEIGH_ADVER ((uint32_t)(1 << 5))
#define BMC_FILT_MULTICAST_IPV6_RA ((uint32_t)(1 << 6))
#define BMC_FILT_MULTICAST_IPV6_RAS ((uint32_t)(1 << 7))
#define BMC_FILT_MULTICAST ((uint32_t)(1 << 8))
#define ND_ROUTER_ADVERT 134
#define ND_NEIGHBOR_ADVERT 136
#define is_mc_allowed_on_bmc(sc, eh) \
(!is_multicast_filt_enabled(sc) && \
ETHER_IS_MULTICAST(eh->ether_dhost) && \
!ETHER_IS_BROADCAST(eh->ether_dhost))
#define is_bc_allowed_on_bmc(sc, eh) \
(!is_broadcast_filt_enabled(sc) && \
ETHER_IS_BROADCAST(eh->ether_dhost))
#define is_arp_allowed_on_bmc(sc, et) \
(is_arp(et) && is_arp_filt_enabled(sc))
#define is_arp(et) (et == ETHERTYPE_ARP)
#define is_arp_filt_enabled(sc) \
(sc->bmc_filt_mask & (BMC_FILT_BROADCAST_ARP))
#define is_dhcp_client_filt_enabled(sc) \
(sc->bmc_filt_mask & BMC_FILT_BROADCAST_DHCP_CLIENT)
#define is_dhcp_srvr_filt_enabled(sc) \
(sc->bmc_filt_mask & BMC_FILT_BROADCAST_DHCP_SERVER)
#define is_nbios_filt_enabled(sc) \
(sc->bmc_filt_mask & BMC_FILT_BROADCAST_NET_BIOS)
#define is_ipv6_na_filt_enabled(sc) \
(sc->bmc_filt_mask & \
BMC_FILT_MULTICAST_IPV6_NEIGH_ADVER)
#define is_ipv6_ra_filt_enabled(sc) \
(sc->bmc_filt_mask & BMC_FILT_MULTICAST_IPV6_RA)
#define is_ipv6_ras_filt_enabled(sc) \
(sc->bmc_filt_mask & BMC_FILT_MULTICAST_IPV6_RAS)
#define is_broadcast_filt_enabled(sc) \
(sc->bmc_filt_mask & BMC_FILT_BROADCAST)
#define is_multicast_filt_enabled(sc) \
(sc->bmc_filt_mask & BMC_FILT_MULTICAST)
#define is_os2bmc_enabled(sc) (sc->flags & OCE_FLAGS_OS2BMC)
#define LRO_FLAGS_HASH_MODE 0x00000001
#define LRO_FLAGS_RSS_MODE 0x00000004
#define LRO_FLAGS_CLSC_IPV4 0x00000010
#define LRO_FLAGS_CLSC_IPV6 0x00000020
#define NIC_RQ_FLAGS_RSS 0x0001
#define NIC_RQ_FLAGS_LRO 0x0020
@@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2013 Emulex
* All rights reserved.
*
@@ -36,11 +38,39 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_mbox.c 333146 2018-05-01 17:39:20Z jpaetzel $ */
#include "oce_if.h"
extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
int
oce_wait_ready(POCE_SOFTC sc)
{
#define SLIPORT_READY_TIMEOUT 30000
uint32_t sliport_status, i;
if (!IS_XE201(sc))
return (-1);
for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET);
if (sliport_status & SLIPORT_STATUS_RDY_MASK)
return 0;
if (sliport_status & SLIPORT_STATUS_ERR_MASK &&
!(sliport_status & SLIPORT_STATUS_RN_MASK)) {
device_printf(sc->dev, "Error detected in the card\n");
return EIO;
}
DELAY(1000);
}
device_printf(sc->dev, "Firmware wait timed out\n");
return (-1);
}
/**
* @brief Reset (firmware) common function
* @param sc software handle to the device
@@ -54,27 +84,37 @@ oce_reset_fun(POCE_SOFTC sc)
struct ioctl_common_function_reset *fwcmd;
int rc = 0;
if (sc->flags & OCE_FLAGS_FUNCRESET_RQD) {
mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
mbx = &mb->mbx;
bzero(mbx, sizeof(struct oce_mbx));
if (IS_XE201(sc)) {
OCE_WRITE_REG32(sc, db, SLIPORT_CONTROL_OFFSET,
SLI_PORT_CONTROL_IP_MASK);
fwcmd = (struct ioctl_common_function_reset *)&mbx->payload;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_COMMON,
OPCODE_COMMON_FUNCTION_RESET,
10, /* MBX_TIMEOUT_SEC */
sizeof(struct
ioctl_common_function_reset),
OCE_MBX_VER_V0);
rc = oce_wait_ready(sc);
if (rc) {
device_printf(sc->dev, "Firmware reset Failed\n");
}
mbx->u0.s.embedded = 1;
mbx->payload_length =
sizeof(struct ioctl_common_function_reset);
rc = oce_mbox_dispatch(sc, 2);
return rc;
}
mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
mbx = &mb->mbx;
bzero(mbx, sizeof(struct oce_mbx));
fwcmd = (struct ioctl_common_function_reset *)&mbx->payload;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_COMMON,
OPCODE_COMMON_FUNCTION_RESET,
10, /* MBX_TIMEOUT_SEC */
sizeof(struct
ioctl_common_function_reset),
OCE_MBX_VER_V0);
mbx->u0.s.embedded = 1;
mbx->payload_length =
sizeof(struct ioctl_common_function_reset);
rc = oce_mbox_dispatch(sc, 2);
return rc;
}
@@ -106,7 +146,7 @@ oce_fw_clean(POCE_SOFTC sc)
*ptr = 0xff;
ret = oce_mbox_dispatch(sc, 2);
return ret;
}
@@ -243,7 +283,7 @@ oce_mbox_init(POCE_SOFTC sc)
ret = oce_mbox_dispatch(sc, 0);
}
return ret;
}
@@ -293,12 +333,12 @@ error:
/**
* @brief Firmware will send gracious notifications during
* attach only after sending first mcc commnad. We
* attach only after sending first mcc commnad. We
* use MCC queue only for getting async and mailbox
* for sending cmds. So to get gracious notifications
* atleast send one dummy command on mcc.
*/
int
int
oce_first_mcc_cmd(POCE_SOFTC sc)
{
struct oce_mbx *mbx;
@@ -308,7 +348,7 @@ oce_first_mcc_cmd(POCE_SOFTC sc)
mbx = RING_GET_PRODUCER_ITEM_VA(mq->ring, struct oce_mbx);
bzero(mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_COMMON,
@@ -366,7 +406,7 @@ oce_mbox_post(POCE_SOFTC sc, struct oce_mbx *mbx, struct oce_mbx_ctx *mbxctx)
*/
mb_cqe = &mb->cqe;
DW_SWAP(u32ptr(&mb_cqe->u0.dw[0]), sizeof(struct oce_mq_cqe));
/* copy mbox mbx back */
bcopy(mb_mbx, mbx, sizeof(struct oce_mbx));
@@ -457,7 +497,7 @@ error:
* @param sc software handle to the device
* @returns 0 on success, EIO on failure
*/
int
int
oce_get_fw_config(POCE_SOFTC sc)
{
struct oce_mbx mbx;
@@ -495,6 +535,10 @@ oce_get_fw_config(POCE_SOFTC sc)
sc->asic_revision = HOST_32(fwcmd->params.rsp.asic_revision);
sc->port_id = HOST_32(fwcmd->params.rsp.port_id);
sc->function_mode = HOST_32(fwcmd->params.rsp.function_mode);
if ((sc->function_mode & (ULP_NIC_MODE | ULP_RDMA_MODE)) ==
(ULP_NIC_MODE | ULP_RDMA_MODE)) {
sc->rdma_flags = OCE_RDMA_FLAG_SUPPORTED;
}
sc->function_caps = HOST_32(fwcmd->params.rsp.function_caps);
if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) {
@@ -504,7 +548,7 @@ oce_get_fw_config(POCE_SOFTC sc)
sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[1].nic_wq_tot);
sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[1].lro_rqid_tot);
}
error:
return ret;
@@ -512,7 +556,7 @@ error:
/**
*
* @brief function to create a device interface
* @brief function to create a device interface
* @param sc software handle to the device
* @param cap_flags capability flags
* @param en_flags enable capability flags
@@ -763,11 +807,11 @@ oce_rss_itbl_init(POCE_SOFTC sc, struct mbx_config_nic_rss *fwcmd)
device_printf(sc->dev, "error: Invalid number of RSS RQ's\n");
rc = ENXIO;
}
}
/* fill log2 value indicating the size of the CPU table */
if (rc == 0)
fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(i));
fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(INDIRECTION_TABLE_ENTRIES));
return rc;
}
@@ -795,7 +839,7 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
fwcmd->params.req.enable_rss = RSS_ENABLE_UDP_IPV4 |
RSS_ENABLE_UDP_IPV6;
} else
version = OCE_MBX_VER_V0;
version = OCE_MBX_VER_V0;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
@@ -808,11 +852,17 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
RSS_ENABLE_TCP_IPV4 |
RSS_ENABLE_IPV6 |
RSS_ENABLE_TCP_IPV6);
fwcmd->params.req.flush = OCE_FLUSH;
if(!sc->enable_hwlro)
fwcmd->params.req.flush = OCE_FLUSH;
else
fwcmd->params.req.flush = 0;
fwcmd->params.req.if_id = LE_32(if_id);
srandom(arc4random()); /* random entropy seed */
read_random(fwcmd->params.req.hash, sizeof(fwcmd->params.req.hash));
rc = oce_rss_itbl_init(sc, fwcmd);
if (rc == 0) {
mbx.u0.s.embedded = 1;
@@ -864,13 +914,13 @@ oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable)
req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
if (enable & 0x02)
req->iface_flags = MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
req->iface_flags |= MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
req->if_id = sc->if_id;
rc = oce_set_common_iface_rx_filter(sc, &sgl);
oce_dma_free(sc, &sgl);
return rc;
}
@@ -968,105 +1018,59 @@ error:
}
int
oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
{
struct oce_mbx mbx;
struct mbx_get_nic_stats_v0 *fwcmd;
int rc = 0;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats_v0);
bzero(fwcmd, sizeof(struct mbx_get_nic_stats_v0));
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
NIC_GET_STATS,
MBX_TIMEOUT_SEC,
sizeof(struct mbx_get_nic_stats_v0),
OCE_MBX_VER_V0);
mbx.u0.s.embedded = 0;
mbx.u0.s.sge_count = 1;
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats_v0);
mbx.payload_length = sizeof(struct mbx_get_nic_stats_v0);
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
/**
* @brief Function to get NIC statistics
* @param sc software handle to the device
* @param *stats pointer to where to store statistics
* @param reset_stats resets statistics of set
* @returns 0 on success, EIO on failure
* @note command depricated in Lancer
* @param sc software handle to the device
* @param *stats pointer to where to store statistics
* @param reset_stats resets statistics of set
* @returns 0 on success, EIO on failure
* @note command depricated in Lancer
*/
int
oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
{
struct oce_mbx mbx;
struct mbx_get_nic_stats *fwcmd;
int rc = 0;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats);
bzero(fwcmd, sizeof(struct mbx_get_nic_stats));
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
NIC_GET_STATS,
MBX_TIMEOUT_SEC,
sizeof(struct mbx_get_nic_stats),
OCE_MBX_VER_V1);
mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */
mbx.u0.s.sge_count = 1; /* using scatter gather instead */
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats);
mbx.payload_length = sizeof(struct mbx_get_nic_stats);
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
rc = oce_mbox_post(sc, &mbx, NULL);
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
#define OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, version) \
int \
oce_mbox_get_nic_stats_v##version(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem) \
{ \
struct oce_mbx mbx; \
struct mbx_get_nic_stats_v##version *fwcmd; \
int rc = 0; \
\
bzero(&mbx, sizeof(struct oce_mbx)); \
fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats_v##version); \
bzero(fwcmd, sizeof(*fwcmd)); \
\
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, \
MBX_SUBSYSTEM_NIC, \
NIC_GET_STATS, \
MBX_TIMEOUT_SEC, \
sizeof(*fwcmd), \
OCE_MBX_VER_V##version); \
\
mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */ \
mbx.u0.s.sge_count = 1; /* using scatter gather instead */ \
\
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE); \
mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr); \
mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr); \
mbx.payload.u0.u1.sgl[0].length = sizeof(*fwcmd); \
mbx.payload_length = sizeof(*fwcmd); \
DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); \
\
rc = oce_mbox_post(sc, &mbx, NULL); \
oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE); \
if (!rc) \
rc = fwcmd->hdr.u0.rsp.status; \
if (rc) \
device_printf(sc->dev, \
"%s failed - cmd status: %d addi status: %d\n", \
__FUNCTION__, rc, \
fwcmd->hdr.u0.rsp.additional_status); \
return rc; \
}
OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 0);
OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 1);
OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 2);
/**
* @brief Function to get pport (physical port) statistics
@@ -1096,7 +1100,7 @@ oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
fwcmd->params.req.reset_stats = reset_stats;
fwcmd->params.req.port_number = sc->port_id;
mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */
mbx.u0.s.sge_count = 1; /* using scatter gather instead */
@@ -1151,7 +1155,7 @@ oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
fwcmd->params.req.reset_stats = reset_stats;
fwcmd->params.req.vport_number = sc->if_id;
mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */
mbx.u0.s.sge_count = 1; /* using scatter gather instead */
@@ -1178,8 +1182,8 @@ oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
/**
* @brief Function to update the muticast filter with
* values in dma_mem
* @brief Function to update the muticast filter with
* values in dma_mem
* @param sc software handle to the device
* @param dma_mem pointer to dma memory region
* @returns 0 on success, EIO on failure
@@ -1272,7 +1276,7 @@ oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
MBX_TIMEOUT_SEC,
sizeof(struct mbx_add_common_iface_mac),
OCE_MBX_VER_V0);
fwcmd->params.req.if_id = (uint16_t) if_id;
bcopy(mac_addr, fwcmd->params.req.mac_address, 6);
@@ -1349,7 +1353,7 @@ oce_mbox_check_native_mode(POCE_SOFTC sc)
sizeof(struct mbx_common_set_function_cap),
OCE_MBX_VER_V0);
fwcmd->params.req.valid_capability_flags = CAP_SW_TIMESTAMPS |
fwcmd->params.req.valid_capability_flags = CAP_SW_TIMESTAMPS |
CAP_BE3_NATIVE_ERX_API;
fwcmd->params.req.capability_flags = CAP_BE3_NATIVE_ERX_API;
@@ -1423,7 +1427,7 @@ oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
uint32_t loopback_type, uint32_t pkt_size, uint32_t num_pkts,
uint64_t pattern)
{
struct oce_mbx mbx;
struct mbx_lowlevel_test_loopback_mode *fwcmd;
int rc = 0;
@@ -1458,7 +1462,7 @@ oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1505,7 +1509,7 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@@ -1687,7 +1691,7 @@ oce_mbox_create_rq(struct oce_rq *rq)
/* oce_page_list will also prepare pages */
num_pages = oce_page_list(rq->ring, &fwcmd->params.req.pages[0]);
if (IS_XE201(sc)) {
fwcmd->params.req.frag_size = rq->cfg.frag_size/2048;
fwcmd->params.req.page_size = 1;
@@ -1699,10 +1703,10 @@ oce_mbox_create_rq(struct oce_rq *rq)
fwcmd->params.req.if_id = sc->if_id;
fwcmd->params.req.max_frame_size = rq->cfg.mtu;
fwcmd->params.req.is_rss_queue = rq->cfg.is_rss_queue;
mbx.u0.s.embedded = 1;
mbx.payload_length = sizeof(struct mbx_create_nic_rq);
rc = oce_mbox_post(sc, &mbx, NULL);
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
@@ -1736,7 +1740,7 @@ oce_mbox_create_wq(struct oce_wq *wq)
if (IS_XE201(sc))
version = OCE_MBX_VER_V1;
else if(IS_BE(sc))
IS_PROFILE_SUPER_NIC(sc) ? (version = OCE_MBX_VER_V2)
IS_PROFILE_SUPER_NIC(sc) ? (version = OCE_MBX_VER_V2)
: (version = OCE_MBX_VER_V0);
else
version = OCE_MBX_VER_V2;
@@ -1842,7 +1846,7 @@ oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable)
uint32_t num_pages, page_size;
int rc = 0;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_create_common_cq *)&mbx.payload;
@@ -1910,7 +1914,7 @@ error:
}
int
int
oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
{
int rc = 0;
@@ -1961,15 +1965,15 @@ oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
}
if(fwcmd->params.rsp.page_num == PAGE_NUM_A0)
{
bcopy((char *)fwcmd->params.rsp.page_data,
(char *)&sfp_vpd_dump_buffer[0],
bcopy((char *)fwcmd->params.rsp.page_data,
(char *)&sfp_vpd_dump_buffer[0],
TRANSCEIVER_A0_SIZE);
}
if(fwcmd->params.rsp.page_num == PAGE_NUM_A2)
{
bcopy((char *)fwcmd->params.rsp.page_data,
(char *)&sfp_vpd_dump_buffer[32],
bcopy((char *)fwcmd->params.rsp.page_data,
(char *)&sfp_vpd_dump_buffer[32],
TRANSCEIVER_A2_SIZE);
}
error:
@@ -2003,13 +2007,13 @@ oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
fwcmd->params.req.num_eq = num;
for (i = 0; i < num; i++) {
fwcmd->params.req.delay[i].eq_id =
fwcmd->params.req.delay[i].eq_id =
htole32(set_eqd[i].eq_id);
fwcmd->params.req.delay[i].phase = 0;
fwcmd->params.req.delay[i].dm =
htole32(set_eqd[i].delay_multiplier);
}
/* command post */
rc = oce_mbox_post(sc, &mbx, NULL);
@@ -2088,7 +2092,7 @@ oce_get_profile_config(POCE_SOFTC sc, uint32_t max_rss)
nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
desc_count = HOST_32(fwcmd->params.rsp.desc_count);
for (i = 0; i < desc_count; i++) {
if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
(nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
nic_desc_valid = TRUE;
break;
@@ -2100,7 +2104,7 @@ oce_get_profile_config(POCE_SOFTC sc, uint32_t max_rss)
rc = -1;
goto error;
}
else {
else {
sc->max_vlans = HOST_16(nic_desc->vlan_count);
sc->nwqs = HOST_16(nic_desc->txq_count);
if (sc->nwqs)
@@ -2136,7 +2140,7 @@ oce_get_func_config(POCE_SOFTC sc)
int i;
boolean_t nic_desc_valid = FALSE;
uint32_t max_rss = 0;
if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
max_rss = OCE_LEGACY_MODE_RSS;
else
@@ -2188,7 +2192,7 @@ oce_get_func_config(POCE_SOFTC sc)
nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
desc_count = HOST_32(fwcmd->params.rsp.desc_count);
for (i = 0; i < desc_count; i++) {
if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
(nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
nic_desc_valid = TRUE;
break;
@@ -2220,3 +2224,149 @@ error:
return rc;
}
/* hw lro functions */
int
oce_mbox_nic_query_lro_capabilities(POCE_SOFTC sc, uint32_t *lro_rq_cnt, uint32_t *lro_flags)
{
struct oce_mbx mbx;
struct mbx_nic_query_lro_capabilities *fwcmd;
int rc = 0;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_nic_query_lro_capabilities *)&mbx.payload;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
0x20,MBX_TIMEOUT_SEC,
sizeof(struct mbx_nic_query_lro_capabilities),
OCE_MBX_VER_V0);
mbx.u0.s.embedded = 1;
mbx.payload_length = sizeof(struct mbx_nic_query_lro_capabilities);
rc = oce_mbox_post(sc, &mbx, NULL);
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
if(lro_flags)
*lro_flags = HOST_32(fwcmd->params.rsp.lro_flags);
if(lro_rq_cnt)
*lro_rq_cnt = HOST_16(fwcmd->params.rsp.lro_rq_cnt);
return rc;
}
int
oce_mbox_nic_set_iface_lro_config(POCE_SOFTC sc, int enable)
{
struct oce_mbx mbx;
struct mbx_nic_set_iface_lro_config *fwcmd;
int rc = 0;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_nic_set_iface_lro_config *)&mbx.payload;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
0x26,MBX_TIMEOUT_SEC,
sizeof(struct mbx_nic_set_iface_lro_config),
OCE_MBX_VER_V0);
mbx.u0.s.embedded = 1;
mbx.payload_length = sizeof(struct mbx_nic_set_iface_lro_config);
fwcmd->params.req.iface_id = sc->if_id;
fwcmd->params.req.lro_flags = 0;
if(enable) {
fwcmd->params.req.lro_flags = LRO_FLAGS_HASH_MODE | LRO_FLAGS_RSS_MODE;
fwcmd->params.req.lro_flags |= LRO_FLAGS_CLSC_IPV4 | LRO_FLAGS_CLSC_IPV6;
fwcmd->params.req.max_clsc_byte_cnt = 64*1024; /* min = 2974, max = 0xfa59 */
fwcmd->params.req.max_clsc_seg_cnt = 43; /* min = 2, max = 64 */
fwcmd->params.req.max_clsc_usec_delay = 18; /* min = 1, max = 256 */
fwcmd->params.req.min_clsc_frame_byte_cnt = 0; /* min = 1, max = 9014 */
}
rc = oce_mbox_post(sc, &mbx, NULL);
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
return rc;
}
int
oce_mbox_create_rq_v2(struct oce_rq *rq)
{
struct oce_mbx mbx;
struct mbx_create_nic_rq_v2 *fwcmd;
POCE_SOFTC sc = rq->parent;
int rc = 0, num_pages = 0;
if (rq->qstate == QCREATED)
return 0;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_create_nic_rq_v2 *)&mbx.payload;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
0x08, MBX_TIMEOUT_SEC,
sizeof(struct mbx_create_nic_rq_v2),
OCE_MBX_VER_V2);
/* oce_page_list will also prepare pages */
num_pages = oce_page_list(rq->ring, &fwcmd->params.req.pages[0]);
fwcmd->params.req.cq_id = rq->cq->cq_id;
fwcmd->params.req.frag_size = rq->cfg.frag_size/2048;
fwcmd->params.req.num_pages = num_pages;
fwcmd->params.req.if_id = sc->if_id;
fwcmd->params.req.max_frame_size = rq->cfg.mtu;
fwcmd->params.req.page_size = 1;
if(rq->cfg.is_rss_queue) {
fwcmd->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO);
}else {
device_printf(sc->dev,
"non rss lro queue should not be created \n");
goto error;
}
mbx.u0.s.embedded = 1;
mbx.payload_length = sizeof(struct mbx_create_nic_rq_v2);
rc = oce_mbox_post(sc, &mbx, NULL);
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
rq->rq_id = HOST_16(fwcmd->params.rsp.rq_id);
rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
error:
return rc;
}
@@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2013 Emulex
* All rights reserved.
*
@@ -36,7 +38,7 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_queue.c 326022 2017-11-20 19:36:21Z pfg $ */
#include "oce_if.h"
@@ -66,7 +68,7 @@ static struct oce_mq *oce_mq_create(POCE_SOFTC sc,
struct oce_eq *eq, uint32_t q_len);
static void oce_mq_free(struct oce_mq *mq);
static int oce_destroy_q(POCE_SOFTC sc, struct oce_mbx
*mbx, size_t req_size, enum qtype qtype);
*mbx, size_t req_size, enum qtype qtype, int version);
struct oce_cq *oce_cq_create(POCE_SOFTC sc,
struct oce_eq *eq,
uint32_t q_len,
@@ -120,9 +122,10 @@ oce_queue_init_all(POCE_SOFTC sc)
aic->min_eqd = OCE_MIN_EQD;
aic->et_eqd = OCE_MIN_EQD;
aic->enable = TRUE;
sc->eq[vector] = oce_eq_create(sc, sc->enable_hwlro ? EQ_LEN_2048 : EQ_LEN_1024,
EQE_SIZE_4,0, vector);
sc->eq[vector] = oce_eq_create(sc, EQ_LEN_1024, EQE_SIZE_4,
0, vector);
if (!sc->eq[vector])
goto error;
}
@@ -169,6 +172,10 @@ oce_queue_release_all(POCE_SOFTC sc)
struct oce_rq *rq;
struct oce_eq *eq;
/* before deleting lro queues, we have to disable hwlro */
if(sc->enable_hwlro)
oce_mbox_nic_set_iface_lro_config(sc, 0);
for_all_rq_queues(sc, rq, i) {
if (rq) {
oce_rq_del(sc->rq[i]);
@@ -254,6 +261,7 @@ oce_wq *oce_wq_init(POCE_SOFTC sc, uint32_t q_len, uint32_t wq_type)
LOCK_CREATE(&wq->tx_lock, "TX_lock");
LOCK_CREATE(&wq->tx_compl_lock, "WQ_HANDLER_LOCK");
#if __FreeBSD_version >= 800000
/* Allocate buf ring for multiqueue*/
@@ -304,6 +312,7 @@ oce_wq_free(struct oce_wq *wq)
buf_ring_free(wq->br, M_DEVBUF);
LOCK_DESTROY(&wq->tx_lock);
LOCK_DESTROY(&wq->tx_compl_lock);
free(wq, M_DEVBUF);
}
@@ -374,7 +383,7 @@ oce_wq_del(struct oce_wq *wq)
fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload;
fwcmd->params.req.wq_id = wq->wq_id;
(void)oce_destroy_q(sc, &mbx,
sizeof(struct mbx_delete_nic_wq), QTYPE_WQ);
sizeof(struct mbx_delete_nic_wq), QTYPE_WQ, 0);
wq->qstate = QDELETED;
}
@@ -422,20 +431,17 @@ oce_rq *oce_rq_init(POCE_SOFTC sc,
rq->cfg.eqd = 0;
rq->lro_pkts_queued = 0;
rq->cfg.is_rss_queue = rss;
rq->packets_in = 0;
rq->packets_out = 0;
rq->pending = 0;
rq->parent = (void *)sc;
rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
1, 0,
BUS_SPACE_MAXADDR,
BUS_SPACE_MAXADDR,
NULL, NULL,
OCE_MAX_RX_SIZE,
1, PAGE_SIZE, 0, NULL, NULL, &rq->tag);
1, 0,
BUS_SPACE_MAXADDR,
BUS_SPACE_MAXADDR,
NULL, NULL,
oce_rq_buf_size,
1, oce_rq_buf_size, 0, NULL, NULL, &rq->tag);
if (rc)
goto free_rq;
@@ -512,10 +518,10 @@ oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq)
POCE_SOFTC sc = rq->parent;
struct oce_cq *cq;
cq = oce_cq_create(sc,
eq,
CQ_LEN_1024,
sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3);
cq = oce_cq_create(sc, eq,
sc->enable_hwlro ? CQ_LEN_2048 : CQ_LEN_1024,
sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3);
if (!cq)
return ENXIO;
@@ -548,14 +554,20 @@ oce_rq_del(struct oce_rq *rq)
POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
struct oce_mbx mbx;
struct mbx_delete_nic_rq *fwcmd;
struct mbx_delete_nic_rq_v1 *fwcmd1;
if (rq->qstate == QCREATED) {
bzero(&mbx, sizeof(mbx));
fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload;
fwcmd->params.req.rq_id = rq->rq_id;
(void)oce_destroy_q(sc, &mbx,
sizeof(struct mbx_delete_nic_rq), QTYPE_RQ);
if(!rq->islro) {
fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload;
fwcmd->params.req.rq_id = rq->rq_id;
(void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq), QTYPE_RQ, 0);
}else {
fwcmd1 = (struct mbx_delete_nic_rq_v1 *)&mbx.payload;
fwcmd1->params.req.rq_id = rq->rq_id;
fwcmd1->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO);
(void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq_v1), QTYPE_RQ, 1);
}
rq->qstate = QDELETED;
}
@@ -632,7 +644,7 @@ oce_eq_del(struct oce_eq *eq)
fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload;
fwcmd->params.req.id = eq->eq_id;
(void)oce_destroy_q(sc, &mbx,
sizeof(struct mbx_destroy_common_eq), QTYPE_EQ);
sizeof(struct mbx_destroy_common_eq), QTYPE_EQ, 0);
}
if (eq->ring != NULL) {
@@ -783,7 +795,7 @@ oce_mq_free(struct oce_mq *mq)
fwcmd->params.req.id = mq->mq_id;
(void) oce_destroy_q(sc, &mbx,
sizeof (struct mbx_destroy_common_mq),
QTYPE_MQ);
QTYPE_MQ, 0);
}
mq->qstate = QDELETED;
}
@@ -810,7 +822,7 @@ oce_mq_free(struct oce_mq *mq)
*/
static int
oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size,
enum qtype qtype)
enum qtype qtype, int version)
{
struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload;
int opcode;
@@ -844,7 +856,7 @@ oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size,
mbx_common_req_hdr_init(hdr, 0, 0, subsys,
opcode, MBX_TIMEOUT_SEC, req_size,
OCE_MBX_VER_V0);
version);
mbx->u0.s.embedded = 1;
mbx->payload_length = (uint32_t) req_size;
@@ -932,7 +944,7 @@ oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq)
fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload;
fwcmd->params.req.id = cq->cq_id;
(void)oce_destroy_q(sc, &mbx,
sizeof(struct mbx_destroy_common_cq), QTYPE_CQ);
sizeof(struct mbx_destroy_common_cq), QTYPE_CQ, 0);
/*NOW destroy the ring */
oce_destroy_ring_buffer(sc, cq->ring);
cq->ring = NULL;
@@ -951,12 +963,17 @@ oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq)
int
oce_start_rq(struct oce_rq *rq)
{
POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
int rc;
rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len);
if(sc->enable_hwlro)
rc = oce_alloc_rx_bufs(rq, 960);
else
rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len - 1);
if (rc == 0)
oce_arm_cq(rq->parent, rq->cq->cq_id, 0, TRUE);
return rc;
}
@@ -1148,7 +1165,7 @@ oce_free_posted_rxbuf(struct oce_rq *rq)
while (rq->pending) {
pd = &rq->pckts[rq->packets_out];
pd = &rq->pckts[rq->ring->cidx];
bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(rq->tag, pd->map);
if (pd->mbuf != NULL) {
@@ -1156,44 +1173,179 @@ oce_free_posted_rxbuf(struct oce_rq *rq)
pd->mbuf = NULL;
}
if ((rq->packets_out + 1) == OCE_RQ_PACKET_ARRAY_SIZE)
rq->packets_out = 0;
else
rq->packets_out++;
RING_GET(rq->ring,1);
rq->pending--;
}
}
void
oce_rx_cq_clean_hwlro(struct oce_rq *rq)
{
struct oce_cq *cq = rq->cq;
POCE_SOFTC sc = rq->parent;
struct nic_hwlro_singleton_cqe *cqe;
struct nic_hwlro_cqe_part2 *cqe2;
int flush_wait = 0;
int flush_compl = 0;
int num_frags = 0;
for (;;) {
bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe);
if(cqe->valid) {
if(cqe->cqe_type == 0) { /* singleton cqe */
/* we should not get singleton cqe after cqe1 on same rq */
if(rq->cqe_firstpart != NULL) {
device_printf(sc->dev, "Got singleton cqe after cqe1 \n");
goto exit_rx_cq_clean_hwlro;
}
num_frags = cqe->pkt_size / rq->cfg.frag_size;
if(cqe->pkt_size % rq->cfg.frag_size)
num_frags++;
oce_discard_rx_comp(rq, num_frags);
/* Check if CQE is flush completion */
if(!cqe->pkt_size)
flush_compl = 1;
cqe->valid = 0;
RING_GET(cq->ring, 1);
}else if(cqe->cqe_type == 0x1) { /* first part */
/* we should not get cqe1 after cqe1 on same rq */
if(rq->cqe_firstpart != NULL) {
device_printf(sc->dev, "Got cqe1 after cqe1 \n");
goto exit_rx_cq_clean_hwlro;
}
rq->cqe_firstpart = (struct nic_hwlro_cqe_part1 *)cqe;
RING_GET(cq->ring, 1);
}else if(cqe->cqe_type == 0x2) { /* second part */
cqe2 = (struct nic_hwlro_cqe_part2 *)cqe;
/* We should not get cqe2 without cqe1 */
if(rq->cqe_firstpart == NULL) {
device_printf(sc->dev, "Got cqe2 without cqe1 \n");
goto exit_rx_cq_clean_hwlro;
}
num_frags = cqe2->coalesced_size / rq->cfg.frag_size;
if(cqe2->coalesced_size % rq->cfg.frag_size)
num_frags++;
/* Flush completion will always come in singleton CQE */
oce_discard_rx_comp(rq, num_frags);
rq->cqe_firstpart->valid = 0;
cqe2->valid = 0;
rq->cqe_firstpart = NULL;
RING_GET(cq->ring, 1);
}
oce_arm_cq(sc, cq->cq_id, 1, FALSE);
if(flush_compl)
break;
}else {
if (flush_wait++ > 100) {
device_printf(sc->dev, "did not receive hwlro flush compl\n");
break;
}
oce_arm_cq(sc, cq->cq_id, 0, TRUE);
DELAY(1000);
}
}
/* After cleanup, leave the CQ in unarmed state */
oce_arm_cq(sc, cq->cq_id, 0, FALSE);
exit_rx_cq_clean_hwlro:
return;
}
void
oce_rx_cq_clean(struct oce_rq *rq)
{
struct oce_nic_rx_cqe *cqe;
struct oce_cq *cq;
POCE_SOFTC sc;
int flush_wait = 0;
int flush_compl = 0;
sc = rq->parent;
cq = rq->cq;
for (;;) {
bus_dmamap_sync(cq->ring->dma.tag,
cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
if(RQ_CQE_VALID(cqe)) {
DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe));
oce_discard_rx_comp(rq, cqe->u0.s.num_fragments);
/* Check if CQE is flush completion */
if((cqe->u0.s.num_fragments==0)&&(cqe->u0.s.pkt_size == 0)&&(cqe->u0.s.error == 0))
flush_compl = 1;
RQ_CQE_INVALIDATE(cqe);
RING_GET(cq->ring, 1);
#if defined(INET6) || defined(INET)
if (IF_LRO_ENABLED(sc))
oce_rx_flush_lro(rq);
#endif
oce_arm_cq(sc, cq->cq_id, 1, FALSE);
if(flush_compl)
break;
}else {
if (flush_wait++ > 100) {
device_printf(sc->dev, "did not receive flush compl\n");
break;
}
oce_arm_cq(sc, cq->cq_id, 0, TRUE);
DELAY(1000);
}
}
/* After cleanup, leave the CQ in unarmed state */
oce_arm_cq(sc, cq->cq_id, 0, FALSE);
}
void
oce_stop_rx(POCE_SOFTC sc)
{
struct oce_mbx mbx;
struct mbx_delete_nic_rq *fwcmd;
struct oce_rq *rq;
int i = 0;
struct oce_mbx mbx;
struct mbx_delete_nic_rq *fwcmd;
struct mbx_delete_nic_rq_v1 *fwcmd1;
struct oce_rq *rq;
int i = 0;
/* before deleting disable hwlro */
if(sc->enable_hwlro)
oce_mbox_nic_set_iface_lro_config(sc, 0);
for_all_rq_queues(sc, rq, i) {
if (rq->qstate == QCREATED) {
/* Delete rxq in firmware */
for_all_rq_queues(sc, rq, i) {
if (rq->qstate == QCREATED) {
/* Delete rxq in firmware */
LOCK(&rq->rx_lock);
bzero(&mbx, sizeof(mbx));
fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload;
fwcmd->params.req.rq_id = rq->rq_id;
bzero(&mbx, sizeof(mbx));
if(!rq->islro) {
fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload;
fwcmd->params.req.rq_id = rq->rq_id;
(void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq), QTYPE_RQ, 0);
}else {
fwcmd1 = (struct mbx_delete_nic_rq_v1 *)&mbx.payload;
fwcmd1->params.req.rq_id = rq->rq_id;
fwcmd1->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO);
(void)oce_destroy_q(sc, &mbx,
sizeof(struct mbx_delete_nic_rq), QTYPE_RQ);
(void)oce_destroy_q(sc,&mbx,sizeof(struct mbx_delete_nic_rq_v1),QTYPE_RQ,1);
}
rq->qstate = QDELETED;
rq->qstate = QDELETED;
DELAY(1);
/* Free posted RX buffers that are not used */
oce_free_posted_rxbuf(rq);
DELAY(1000);
}
}
if(!rq->islro)
oce_rx_cq_clean(rq);
else
oce_rx_cq_clean_hwlro(rq);
/* Free posted RX buffers that are not used */
oce_free_posted_rxbuf(rq);
UNLOCK(&rq->rx_lock);
}
}
}
@@ -1207,16 +1359,28 @@ oce_start_rx(POCE_SOFTC sc)
for_all_rq_queues(sc, rq, i) {
if (rq->qstate == QCREATED)
continue;
rc = oce_mbox_create_rq(rq);
if((i == 0) || (!sc->enable_hwlro)) {
rc = oce_mbox_create_rq(rq);
if (rc)
goto error;
rq->islro = 0;
}else {
rc = oce_mbox_create_rq_v2(rq);
if (rc)
goto error;
rq->islro = 1;
}
/* reset queue pointers */
rq->qstate = QCREATED;
rq->pending = 0;
rq->ring->cidx = 0;
rq->ring->pidx = 0;
}
if(sc->enable_hwlro) {
rc = oce_mbox_nic_set_iface_lro_config(sc, 1);
if (rc)
goto error;
/* reset queue pointers */
rq->qstate = QCREATED;
rq->pending = 0;
rq->ring->cidx = 0;
rq->ring->pidx = 0;
rq->packets_in = 0;
rq->packets_out = 0;
}
DELAY(1);
@@ -1229,6 +1393,7 @@ oce_start_rx(POCE_SOFTC sc)
}
DELAY(1);
return rc;
error:
device_printf(sc->dev, "Start RX failed\n");
@@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2013 Emulex
* All rights reserved.
*
@@ -36,13 +38,14 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_sysctl.c 326022 2017-11-20 19:36:21Z pfg $ */
#include "oce_if.h"
static void copy_stats_to_sc_xe201(POCE_SOFTC sc);
static void copy_stats_to_sc_be3(POCE_SOFTC sc);
static void copy_stats_to_sc_be2(POCE_SOFTC sc);
static void copy_stats_to_sc_sh(POCE_SOFTC sc);
static int oce_sysctl_loopback(SYSCTL_HANDLER_ARGS);
static int oce_sys_aic_enable(SYSCTL_HANDLER_ARGS);
static int oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
@@ -103,7 +106,7 @@ oce_add_sysctls(POCE_SOFTC sc)
sizeof(oce_max_rsp_handled),
"Maximum receive frames handled per interupt");
if ((sc->function_mode & FNM_FLEX10_MODE) ||
if ((sc->function_mode & FNM_FLEX10_MODE) ||
(sc->function_mode & FNM_UMC_MODE))
SYSCTL_ADD_UINT(ctx, child,
OID_AUTO, "speed",
@@ -182,9 +185,11 @@ oce_sys_aic_enable(SYSCTL_HANDLER_ARGS)
POCE_SOFTC sc = (struct oce_softc *)arg1;
struct oce_aic_obj *aic;
/* set current value for proper sysctl logging */
value = sc->aic_obj[0].enable;
status = sysctl_handle_int(oidp, &value, 0, req);
if (status || !req->newptr)
return status;
return status;
for (vector = 0; vector < sc->intr_count; vector++) {
aic = &sc->aic_obj[vector];
@@ -207,12 +212,12 @@ static int
oce_sysctl_loopback(SYSCTL_HANDLER_ARGS)
{
int value = 0;
uint32_t status;
uint32_t status;
struct oce_softc *sc = (struct oce_softc *)arg1;
status = sysctl_handle_int(oidp, &value, 0, req);
if (status || !req->newptr)
return status;
return status;
if (value != 1) {
device_printf(sc->dev,
@@ -266,7 +271,7 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
if (IS_BE(sc)) {
if ((sc->flags & OCE_FLAGS_BE2)) {
device_printf(sc->dev,
device_printf(sc->dev,
"Flashing not supported for BE2 yet.\n");
status = 1;
goto done;
@@ -482,34 +487,34 @@ ret:
return rc;
}
#define UFI_TYPE2 2
#define UFI_TYPE3 3
#define UFI_TYPE3R 10
#define UFI_TYPE4 4
#define UFI_TYPE4R 11
#define UFI_TYPE2 2
#define UFI_TYPE3 3
#define UFI_TYPE3R 10
#define UFI_TYPE4 4
#define UFI_TYPE4R 11
static int oce_get_ufi_type(POCE_SOFTC sc,
const struct flash_file_hdr *fhdr)
const struct flash_file_hdr *fhdr)
{
if (fhdr == NULL)
goto be_get_ufi_exit;
if (fhdr == NULL)
goto be_get_ufi_exit;
if (IS_SH(sc) && fhdr->build[0] == '4') {
if (fhdr->asic_type_rev >= 0x10)
return UFI_TYPE4R;
else
return UFI_TYPE4;
} else if (IS_BE3(sc) && fhdr->build[0] == '3') {
if (fhdr->asic_type_rev == 0x10)
return UFI_TYPE3R;
else
return UFI_TYPE3;
} else if (IS_BE2(sc) && fhdr->build[0] == '2')
return UFI_TYPE2;
if (IS_SH(sc) && fhdr->build[0] == '4') {
if (fhdr->asic_type_rev >= 0x10)
return UFI_TYPE4R;
else
return UFI_TYPE4;
} else if (IS_BE3(sc) && fhdr->build[0] == '3') {
if (fhdr->asic_type_rev == 0x10)
return UFI_TYPE3R;
else
return UFI_TYPE3;
} else if (IS_BE2(sc) && fhdr->build[0] == '2')
return UFI_TYPE2;
be_get_ufi_exit:
device_printf(sc->dev,
"UFI and Interface are not compatible for flashing\n");
return -1;
device_printf(sc->dev,
"UFI and Interface are not compatible for flashing\n");
return -1;
}
@@ -715,12 +720,12 @@ oce_add_stats_sysctls_be3(POCE_SOFTC sc,
stats = &sc->oce_stats_info;
rx_stats_node = SYSCTL_ADD_NODE(ctx,
SYSCTL_CHILDREN(stats_node),
OID_AUTO,"rx", CTLFLAG_RD,
SYSCTL_CHILDREN(stats_node),
OID_AUTO,"rx", CTLFLAG_RD,
NULL, "RX Ethernet Statistics");
rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_pkts",
CTLFLAG_RD, &stats->rx.t_rx_pkts,
"Total Received Packets");
@@ -748,15 +753,15 @@ oce_add_stats_sysctls_be3(POCE_SOFTC sc,
SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "control_frames",
CTLFLAG_RD, &stats->u0.be.rx_control_frames, 0,
"Control Frames");
for (i = 0; i < sc->nrqs; i++) {
sprintf(prefix, "queue%d",i);
queue_stats_node = SYSCTL_ADD_NODE(ctx,
queue_stats_node = SYSCTL_ADD_NODE(ctx,
SYSCTL_CHILDREN(rx_stats_node),
OID_AUTO, prefix, CTLFLAG_RD,
NULL, "Queue name");
queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_pkts",
CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_pkts,
"Receive Packets");
@@ -771,21 +776,25 @@ oce_add_stats_sysctls_be3(POCE_SOFTC sc,
&sc->rq[i]->rx_stats.rx_mcast_pkts, 0,
"Received Multicast Packets");
SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
"rx_ucast_pkts", CTLFLAG_RD,
"rx_ucast_pkts", CTLFLAG_RD,
&sc->rq[i]->rx_stats.rx_ucast_pkts, 0,
"Received Unicast Packets");
SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rxcp_err",
CTLFLAG_RD, &sc->rq[i]->rx_stats.rxcp_err, 0,
"Received Completion Errors");
if(IS_SH(sc)) {
SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rx_drops_no_frags",
CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_drops_no_frags, 0,
"num of packet drops due to no fragments");
}
}
rx_stats_node = SYSCTL_ADD_NODE(ctx,
SYSCTL_CHILDREN(rx_stats_node),
OID_AUTO, "err", CTLFLAG_RD,
NULL, "Receive Error Stats");
rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "crc_errs",
CTLFLAG_RD, &stats->u0.be.rx_crc_errors, 0,
"CRC Errors");
@@ -883,7 +892,7 @@ oce_add_stats_sysctls_be3(POCE_SOFTC sc,
for (i = 0; i < sc->nwqs; i++) {
sprintf(prefix, "queue%d",i);
queue_stats_node = SYSCTL_ADD_NODE(ctx,
queue_stats_node = SYSCTL_ADD_NODE(ctx,
SYSCTL_CHILDREN(tx_stats_node),
OID_AUTO, prefix, CTLFLAG_RD,
NULL, "Queue name");
@@ -938,7 +947,7 @@ oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
NULL, "RX Ethernet Statistics");
rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_pkts",
CTLFLAG_RD, &stats->rx.t_rx_pkts,
"Total Received Packets");
@@ -963,15 +972,15 @@ oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
SYSCTL_ADD_UQUAD(ctx, rx_stat_list, OID_AUTO, "control_frames",
CTLFLAG_RD, &stats->u0.xe201.rx_control_frames,
"Control Frames");
for (i = 0; i < sc->nrqs; i++) {
sprintf(prefix, "queue%d",i);
queue_stats_node = SYSCTL_ADD_NODE(ctx,
queue_stats_node = SYSCTL_ADD_NODE(ctx,
SYSCTL_CHILDREN(rx_stats_node),
OID_AUTO, prefix, CTLFLAG_RD,
NULL, "Queue name");
queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_pkts",
CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_pkts,
"Receive Packets");
@@ -992,7 +1001,7 @@ oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rxcp_err",
CTLFLAG_RD, &sc->rq[i]->rx_stats.rxcp_err, 0,
"Received Completion Errors");
}
rx_stats_node = SYSCTL_ADD_NODE(ctx,
@@ -1000,7 +1009,7 @@ oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
OID_AUTO, "err", CTLFLAG_RD,
NULL, "Receive Error Stats");
rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
SYSCTL_ADD_UQUAD(ctx, rx_stat_list, OID_AUTO, "crc_errs",
CTLFLAG_RD, &stats->u0.xe201.rx_crc_errors,
"CRC Errors");
@@ -1086,7 +1095,7 @@ oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
for (i = 0; i < sc->nwqs; i++) {
sprintf(prefix, "queue%d",i);
queue_stats_node = SYSCTL_ADD_NODE(ctx,
queue_stats_node = SYSCTL_ADD_NODE(ctx,
SYSCTL_CHILDREN(tx_stats_node),
OID_AUTO, prefix, CTLFLAG_RD,
NULL, "Queue name");
@@ -1120,23 +1129,23 @@ oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
}
void
void
oce_refresh_queue_stats(POCE_SOFTC sc)
{
struct oce_drv_stats *adapter_stats;
int i;
adapter_stats = &sc->oce_stats_info;
/* Caluculate total TX and TXstats from all queues */
bzero(&adapter_stats->rx, sizeof(struct oce_rx_stats));
for (i = 0; i < sc->nrqs; i++) {
adapter_stats->rx.t_rx_pkts += sc->rq[i]->rx_stats.rx_pkts;
adapter_stats->rx.t_rx_bytes += sc->rq[i]->rx_stats.rx_bytes;
adapter_stats->rx.t_rx_frags += sc->rq[i]->rx_stats.rx_frags;
adapter_stats->rx.t_rx_mcast_pkts +=
adapter_stats->rx.t_rx_mcast_pkts +=
sc->rq[i]->rx_stats.rx_mcast_pkts;
adapter_stats->rx.t_rx_ucast_pkts +=
sc->rq[i]->rx_stats.rx_ucast_pkts;
@@ -1314,10 +1323,10 @@ copy_stats_to_sc_be2(POCE_SOFTC sc)
pmem = &nic_mbx->params.rsp.stats.pmem;
rxf_stats = &nic_mbx->params.rsp.stats.rxf;
port_stats = &nic_mbx->params.rsp.stats.rxf.port[port];
adapter_stats = &sc->oce_stats_info.u0.be;
/* Update stats */
adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
@@ -1345,7 +1354,7 @@ copy_stats_to_sc_be2(POCE_SOFTC sc)
port_stats->rx_alignment_symbol_errors;
adapter_stats->tx_pauseframes = port_stats->tx_pauseframes;
adapter_stats->tx_controlframes = port_stats->tx_controlframes;
if (sc->if_id)
adapter_stats->jabber_events = rxf_stats->port1_jabber_events;
else
@@ -1372,10 +1381,10 @@ copy_stats_to_sc_be3(POCE_SOFTC sc)
struct oce_pmem_stats *pmem;
struct oce_rxf_stats_v1 *rxf_stats;
struct oce_port_rxf_stats_v1 *port_stats;
struct mbx_get_nic_stats *nic_mbx;
struct mbx_get_nic_stats_v1 *nic_mbx;
uint32_t port = sc->port_id;
nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats);
nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats_v1);
pmem = &nic_mbx->params.rsp.stats.pmem;
rxf_stats = &nic_mbx->params.rsp.stats.rxf;
port_stats = &nic_mbx->params.rsp.stats.rxf.port[port];
@@ -1429,18 +1438,93 @@ copy_stats_to_sc_be3(POCE_SOFTC sc)
adapter_stats->eth_red_drops = pmem->eth_red_drops;
}
static void
copy_stats_to_sc_sh(POCE_SOFTC sc)
{
struct oce_be_stats *adapter_stats;
struct oce_pmem_stats *pmem;
struct oce_rxf_stats_v2 *rxf_stats;
struct oce_port_rxf_stats_v2 *port_stats;
struct mbx_get_nic_stats_v2 *nic_mbx;
struct oce_erx_stats_v2 *erx_stats;
uint32_t port = sc->port_id;
nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats_v2);
pmem = &nic_mbx->params.rsp.stats.pmem;
rxf_stats = &nic_mbx->params.rsp.stats.rxf;
erx_stats = &nic_mbx->params.rsp.stats.erx;
port_stats = &nic_mbx->params.rsp.stats.rxf.port[port];
adapter_stats = &sc->oce_stats_info.u0.be;
/* Update stats */
adapter_stats->pmem_fifo_overflow_drop =
port_stats->pmem_fifo_overflow_drop;
adapter_stats->rx_priority_pause_frames =
port_stats->rx_priority_pause_frames;
adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
adapter_stats->rx_control_frames = port_stats->rx_control_frames;
adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors;
adapter_stats->rx_frame_too_long = port_stats->rx_frame_too_long;
adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt;
adapter_stats->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
adapter_stats->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
adapter_stats->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
adapter_stats->rx_dropped_tcp_length =
port_stats->rx_dropped_tcp_length;
adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small;
adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short;
adapter_stats->rx_out_range_errors = port_stats->rx_out_range_errors;
adapter_stats->rx_dropped_header_too_small =
port_stats->rx_dropped_header_too_small;
adapter_stats->rx_input_fifo_overflow_drop =
port_stats->rx_input_fifo_overflow_drop;
adapter_stats->rx_address_match_errors =
port_stats->rx_address_match_errors;
adapter_stats->rx_alignment_symbol_errors =
port_stats->rx_alignment_symbol_errors;
adapter_stats->rxpp_fifo_overflow_drop =
port_stats->rxpp_fifo_overflow_drop;
adapter_stats->tx_pauseframes = port_stats->tx_pauseframes;
adapter_stats->tx_controlframes = port_stats->tx_controlframes;
adapter_stats->jabber_events = port_stats->jabber_events;
adapter_stats->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
adapter_stats->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
adapter_stats->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
adapter_stats->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
adapter_stats->forwarded_packets = rxf_stats->forwarded_packets;
adapter_stats->rx_drops_mtu = rxf_stats->rx_drops_mtu;
adapter_stats->rx_drops_no_tpre_descr =
rxf_stats->rx_drops_no_tpre_descr;
adapter_stats->rx_drops_too_many_frags =
rxf_stats->rx_drops_too_many_frags;
adapter_stats->eth_red_drops = pmem->eth_red_drops;
/* populate erx stats */
{ int i;
for (i = 0; i < sc->nrqs; i++)
sc->rq[i]->rx_stats.rx_drops_no_frags = erx_stats->rx_drops_no_fragments[sc->rq[i]->rq_id];
}
}
int
oce_stats_init(POCE_SOFTC sc)
{
int rc = 0, sz;
if (IS_BE(sc) || IS_SH(sc)) {
if (sc->flags & OCE_FLAGS_BE2)
sz = sizeof(struct mbx_get_nic_stats_v0);
else
sz = sizeof(struct mbx_get_nic_stats);
} else
int rc = 0, sz = 0;
if( IS_BE2(sc) )
sz = sizeof(struct mbx_get_nic_stats_v0);
else if( IS_BE3(sc) )
sz = sizeof(struct mbx_get_nic_stats_v1);
else if( IS_SH(sc))
sz = sizeof(struct mbx_get_nic_stats_v2);
else if( IS_XE201(sc) )
sz = sizeof(struct mbx_get_pport_stats);
rc = oce_dma_alloc(sc, sz, &sc->stats_mem, 0);
@@ -1463,27 +1547,28 @@ oce_refresh_nic_stats(POCE_SOFTC sc)
{
int rc = 0, reset = 0;
if (IS_BE(sc) || IS_SH(sc)) {
if (sc->flags & OCE_FLAGS_BE2) {
rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem);
if (!rc)
copy_stats_to_sc_be2(sc);
} else {
rc = oce_mbox_get_nic_stats(sc, &sc->stats_mem);
if (!rc)
copy_stats_to_sc_be3(sc);
}
} else {
if( IS_BE2(sc) ) {
rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem);
if (!rc)
copy_stats_to_sc_be2(sc);
}else if( IS_BE3(sc) ) {
rc = oce_mbox_get_nic_stats_v1(sc, &sc->stats_mem);
if (!rc)
copy_stats_to_sc_be3(sc);
}else if( IS_SH(sc)) {
rc = oce_mbox_get_nic_stats_v2(sc, &sc->stats_mem);
if (!rc)
copy_stats_to_sc_sh(sc);
}else if( IS_XE201(sc) ){
rc = oce_mbox_get_pport_stats(sc, &sc->stats_mem, reset);
if (!rc)
copy_stats_to_sc_xe201(sc);
}
return rc;
}
static int
static int
oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS)
{
int result = 0, error;
@@ -0,0 +1,121 @@
/*-
* Copyright (C) 2013 Emulex
* All rights reserved.
*
* 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.
*
* 3. Neither the name of the Emulex 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.
*
* Contact Information:
* freebsd-drivers@emulex.com
*
* Emulex
* 3333 Susan Street
* Costa Mesa, CA 92626
*/
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_user.h 306219 2016-09-22 22:51:11Z jpaetzel $ */
struct oce_mbx;
struct oce_softc;
struct mbx_hdr;
enum oce_interrupt_mode {
OCE_INTERRUPT_MODE_MSIX = 0,
OCE_INTERRUPT_MODE_INTX = 1,
OCE_INTERRUPT_MODE_MSI = 2,
};
#define MAX_ROCE_MSIX_VECTORS 16
#define MIN_ROCE_MSIX_VECTORS 1
#define ROCE_MSIX_VECTORS 2
struct oce_dev_info {
device_t dev;
struct ifnet *ifp;
struct oce_softc *softc;
bus_space_handle_t db_bhandle;
bus_space_tag_t db_btag;
uint64_t unmapped_db;
uint32_t unmapped_db_len;
uint32_t db_page_size;
uint64_t dpp_unmapped_addr;
uint32_t dpp_unmapped_len;
uint8_t mac_addr[6];
uint32_t dev_family;
uint16_t vendor_id;
uint16_t dev_id;
enum oce_interrupt_mode intr_mode;
struct {
int num_vectors;
int start_vector;
uint32_t vector_list[MAX_ROCE_MSIX_VECTORS];
} msix;
uint32_t flags;
#define OCE_RDMA_INFO_RDMA_SUPPORTED 0x00000001
};
#define OCE_GEN2_FAMILY 2
#ifdef notdef
struct oce_mbx_ctx {
struct oce_mbx *mbx;
void (*cb) (void *ctx);
void *cb_ctx;
};
#endif
struct oce_mbx_ctx;
typedef struct oce_rdma_info {
int size;
void (*close)(void);
int (*mbox_post)(struct oce_softc *sc,
struct oce_mbx *mbx,
struct oce_mbx_ctx *mbxctx);
void (*common_req_hdr_init)(struct mbx_hdr *hdr,
uint8_t dom,
uint8_t port,
uint8_t subsys,
uint8_t opcode,
uint32_t timeout,
uint32_t pyld_len,
uint8_t version);
void (*get_mac_addr)(struct oce_softc *sc,
uint8_t *macaddr);
} OCE_RDMA_INFO, *POCE_RDMA_INFO;
#define OCE_RDMA_INFO_SIZE (sizeof(OCE_RDMA_INFO))
typedef struct oce_rdma_if {
int size;
int (*announce)(struct oce_dev_info *devinfo);
} OCE_RDMA_IF, *POCE_RDMA_IF;
#define OCE_RDMA_IF_SIZE (sizeof(OCE_RDMA_IF))
int oce_register_rdma(POCE_RDMA_INFO rdma_info, POCE_RDMA_IF rdma_if);
@@ -1,4 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (C) 2013 Emulex
* All rights reserved.
*
@@ -36,7 +38,7 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
/* $FreeBSD: releng/12.0/sys/dev/oce/oce_util.c 326022 2017-11-20 19:36:21Z pfg $ */
#include "oce_if.h"