emulex_oce: Upgrade to FreeBSD 12.
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user