mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
bnxt_en: Add PFC, ETS & App TLVs protocols support
Created new directory "bnxt_en" in /dev/bnxt and /modules/bnxt and moved source files and Makefile into respective directory. ETS support: - Added new files bnxt_dcb.c & bnxt_dcb.h - Added sysctl node 'dcb' and created handlers 'ets' and 'dcbx_cap' - Add logic to validate user input and configure ETS in the firmware - Updated makefile to include bnxt_dcb.c & bnxt_dcb.h PFC support: - Created sysctl handlers 'pfc' under node 'dcb' - Added logic to validate user input and configure PFC in the firmware. App TLV support: - Created 3 new sysctl handlers under node 'dcb' - set_apptlv (write only): Sets a specified TLV - del_apptlv (write only): Deletes a specified TLV - list_apptlv (read only): Lists all APP TLVs configured - Added logic to validate user input and configure APP TLVs in the firmware. Added Below DCB ops for management interface: - Set PFC, Get PFC, Set ETS, Get ETS, Add App_TLV, Del App_TLV Lst App_TLV Reviewed by: imp Approved by: imp Differential revision: https://reviews.freebsd.org/D45005
This commit is contained in:
parent
1c45a62a2f
commit
35b53f8c98
|
@ -44,6 +44,7 @@
|
|||
#include <net/iflib.h>
|
||||
|
||||
#include "hsi_struct_def.h"
|
||||
#include "bnxt_dcb.h"
|
||||
|
||||
/* PCI IDs */
|
||||
#define BROADCOM_VENDOR_ID 0x14E4
|
||||
|
@ -359,9 +360,9 @@ enum bnxt_cp_type {
|
|||
BNXT_SHARED
|
||||
};
|
||||
|
||||
struct bnxt_cos_queue {
|
||||
uint8_t id;
|
||||
uint8_t profile;
|
||||
struct bnxt_queue_info {
|
||||
uint8_t queue_id;
|
||||
uint8_t queue_profile;
|
||||
};
|
||||
|
||||
struct bnxt_func_info {
|
||||
|
@ -532,6 +533,13 @@ struct bnxt_ver_info {
|
|||
uint8_t hwrm_min_major;
|
||||
uint8_t hwrm_min_minor;
|
||||
uint8_t hwrm_min_update;
|
||||
uint64_t fw_ver_code;
|
||||
#define BNXT_FW_VER_CODE(maj, min, bld, rsv) \
|
||||
((uint64_t)(maj) << 48 | (uint64_t)(min) << 32 | (uint64_t)(bld) << 16 | (rsv))
|
||||
#define BNXT_FW_MAJ(softc) ((softc)->ver_info->fw_ver_code >> 48)
|
||||
#define BNXT_FW_MIN(softc) (((softc)->ver_info->fw_ver_code >> 32) & 0xffff)
|
||||
#define BNXT_FW_BLD(softc) (((softc)->ver_info->fw_ver_code >> 16) & 0xffff)
|
||||
#define BNXT_FW_RSV(softc) (((softc)->ver_info->fw_ver_code) & 0xffff)
|
||||
|
||||
struct sysctl_ctx_list ver_ctx;
|
||||
struct sysctl_oid *ver_oid;
|
||||
|
@ -644,38 +652,52 @@ struct bnxt_ctx_mem_info {
|
|||
};
|
||||
|
||||
struct bnxt_hw_resc {
|
||||
uint16_t min_rsscos_ctxs;
|
||||
uint16_t max_rsscos_ctxs;
|
||||
uint16_t min_cp_rings;
|
||||
uint16_t max_cp_rings;
|
||||
uint16_t resv_cp_rings;
|
||||
uint16_t min_tx_rings;
|
||||
uint16_t max_tx_rings;
|
||||
uint16_t resv_tx_rings;
|
||||
uint16_t max_tx_sch_inputs;
|
||||
uint16_t min_rx_rings;
|
||||
uint16_t max_rx_rings;
|
||||
uint16_t resv_rx_rings;
|
||||
uint16_t min_hw_ring_grps;
|
||||
uint16_t max_hw_ring_grps;
|
||||
uint16_t resv_hw_ring_grps;
|
||||
uint16_t min_l2_ctxs;
|
||||
uint16_t max_l2_ctxs;
|
||||
uint16_t min_vnics;
|
||||
uint16_t max_vnics;
|
||||
uint16_t resv_vnics;
|
||||
uint16_t min_stat_ctxs;
|
||||
uint16_t max_stat_ctxs;
|
||||
uint16_t resv_stat_ctxs;
|
||||
uint16_t max_nqs;
|
||||
uint16_t max_irqs;
|
||||
uint16_t resv_irqs;
|
||||
uint16_t min_rsscos_ctxs;
|
||||
uint16_t max_rsscos_ctxs;
|
||||
uint16_t min_cp_rings;
|
||||
uint16_t max_cp_rings;
|
||||
uint16_t resv_cp_rings;
|
||||
uint16_t min_tx_rings;
|
||||
uint16_t max_tx_rings;
|
||||
uint16_t resv_tx_rings;
|
||||
uint16_t max_tx_sch_inputs;
|
||||
uint16_t min_rx_rings;
|
||||
uint16_t max_rx_rings;
|
||||
uint16_t resv_rx_rings;
|
||||
uint16_t min_hw_ring_grps;
|
||||
uint16_t max_hw_ring_grps;
|
||||
uint16_t resv_hw_ring_grps;
|
||||
uint16_t min_l2_ctxs;
|
||||
uint16_t max_l2_ctxs;
|
||||
uint16_t min_vnics;
|
||||
uint16_t max_vnics;
|
||||
uint16_t resv_vnics;
|
||||
uint16_t min_stat_ctxs;
|
||||
uint16_t max_stat_ctxs;
|
||||
uint16_t resv_stat_ctxs;
|
||||
uint16_t max_nqs;
|
||||
uint16_t max_irqs;
|
||||
uint16_t resv_irqs;
|
||||
}
|
||||
|
||||
enum bnxt_type_ets {
|
||||
BNXT_TYPE_ETS_TSA = 0,
|
||||
BNXT_TYPE_ETS_PRI2TC,
|
||||
BNXT_TYPE_ETS_TCBW,
|
||||
BNXT_TYPE_ETS_MAX
|
||||
};
|
||||
|
||||
#define BNXT_LLQ(q_profile) \
|
||||
((q_profile) == HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS_ROCE)
|
||||
#define BNXT_CNPQ(q_profile) \
|
||||
((q_profile) == HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY_ROCE_CNP)
|
||||
static const char *const BNXT_ETS_TYPE_STR[] = {
|
||||
"tsa",
|
||||
"pri2tc",
|
||||
"tcbw",
|
||||
};
|
||||
|
||||
static const char *const BNXT_ETS_HELP_STR[] = {
|
||||
"X is 1 (strict), 0 (ets)",
|
||||
"TC values for pri 0 to 7",
|
||||
"TC BW values for pri 0 to 7, Sum should be 100",
|
||||
};
|
||||
|
||||
#define BNXT_HWRM_MAX_REQ_LEN (softc->hwrm_max_req_len)
|
||||
|
||||
|
@ -684,6 +706,10 @@ struct bnxt_softc_list {
|
|||
struct bnxt_softc *softc;
|
||||
};
|
||||
|
||||
#ifndef BIT_ULL
|
||||
#define BIT_ULL(nr) (1ULL << (nr))
|
||||
#endif
|
||||
|
||||
struct bnxt_softc {
|
||||
device_t dev;
|
||||
if_ctx_t ctx;
|
||||
|
@ -710,6 +736,8 @@ struct bnxt_softc {
|
|||
#define BNXT_FLAG_CHIP_P5 0x0020
|
||||
#define BNXT_FLAG_TPA 0x0040
|
||||
#define BNXT_FLAG_FW_CAP_EXT_STATS 0x0080
|
||||
#define BNXT_FLAG_MULTI_HOST 0x0100
|
||||
#define BNXT_FLAG_MULTI_ROOT 0x0200
|
||||
uint32_t flags;
|
||||
#define BNXT_STATE_LINK_CHANGE (0)
|
||||
#define BNXT_STATE_MAX (BNXT_STATE_LINK_CHANGE + 1)
|
||||
|
@ -732,13 +760,23 @@ struct bnxt_softc {
|
|||
uint16_t hwrm_max_ext_req_len;
|
||||
uint32_t hwrm_spec_code;
|
||||
|
||||
#define BNXT_MAX_COS_QUEUE 8
|
||||
#define BNXT_MAX_QUEUE 8
|
||||
uint8_t max_tc;
|
||||
uint8_t max_lltc; /* lossless TCs */
|
||||
struct bnxt_cos_queue q_info[BNXT_MAX_COS_QUEUE];
|
||||
uint8_t tc_to_qidx[BNXT_MAX_COS_QUEUE];
|
||||
uint8_t q_ids[BNXT_MAX_COS_QUEUE];
|
||||
uint8_t max_q;
|
||||
uint8_t max_lltc;
|
||||
struct bnxt_queue_info tx_q_info[BNXT_MAX_QUEUE];
|
||||
struct bnxt_queue_info rx_q_info[BNXT_MAX_QUEUE];
|
||||
uint8_t tc_to_qidx[BNXT_MAX_QUEUE];
|
||||
uint8_t tx_q_ids[BNXT_MAX_QUEUE];
|
||||
uint8_t rx_q_ids[BNXT_MAX_QUEUE];
|
||||
uint8_t tx_max_q;
|
||||
uint8_t rx_max_q;
|
||||
uint8_t is_asym_q;
|
||||
|
||||
struct bnxt_ieee_ets *ieee_ets;
|
||||
struct bnxt_ieee_pfc *ieee_pfc;
|
||||
uint8_t dcbx_cap;
|
||||
uint8_t default_pri;
|
||||
uint8_t max_dscp_value;
|
||||
|
||||
uint64_t admin_ticks;
|
||||
struct iflib_dma_info hw_rx_port_stats;
|
||||
|
@ -782,6 +820,8 @@ struct bnxt_softc {
|
|||
struct sysctl_oid *hw_lro_oid;
|
||||
struct sysctl_ctx_list flow_ctrl_ctx;
|
||||
struct sysctl_oid *flow_ctrl_oid;
|
||||
struct sysctl_ctx_list dcb_ctx;
|
||||
struct sysctl_oid *dcb_oid;
|
||||
|
||||
struct bnxt_ver_info *ver_info;
|
||||
struct bnxt_nvram_info *nvm_info;
|
||||
|
@ -796,13 +836,78 @@ struct bnxt_softc {
|
|||
uint16_t tx_coal_usecs;
|
||||
uint16_t tx_coal_usecs_irq;
|
||||
uint16_t tx_coal_frames;
|
||||
uint16_t tx_coal_frames_irq;
|
||||
uint16_t tx_coal_frames_irq;
|
||||
|
||||
#define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2)
|
||||
#define BNXT_DEF_STATS_COAL_TICKS 1000000
|
||||
#define BNXT_MIN_STATS_COAL_TICKS 250000
|
||||
#define BNXT_MAX_STATS_COAL_TICKS 1000000
|
||||
|
||||
uint64_t fw_cap;
|
||||
#define BNXT_FW_CAP_SHORT_CMD BIT_ULL(0)
|
||||
#define BNXT_FW_CAP_LLDP_AGENT BIT_ULL(1)
|
||||
#define BNXT_FW_CAP_DCBX_AGENT BIT_ULL(2)
|
||||
#define BNXT_FW_CAP_NEW_RM BIT_ULL(3)
|
||||
#define BNXT_FW_CAP_IF_CHANGE BIT_ULL(4)
|
||||
#define BNXT_FW_CAP_LINK_ADMIN BIT_ULL(5)
|
||||
#define BNXT_FW_CAP_VF_RES_MIN_GUARANTEED BIT_ULL(6)
|
||||
#define BNXT_FW_CAP_KONG_MB_CHNL BIT_ULL(7)
|
||||
#define BNXT_FW_CAP_ADMIN_MTU BIT_ULL(8)
|
||||
#define BNXT_FW_CAP_ADMIN_PF BIT_ULL(9)
|
||||
#define BNXT_FW_CAP_OVS_64BIT_HANDLE BIT_ULL(10)
|
||||
#define BNXT_FW_CAP_TRUSTED_VF BIT_ULL(11)
|
||||
#define BNXT_FW_CAP_VF_VNIC_NOTIFY BIT_ULL(12)
|
||||
#define BNXT_FW_CAP_ERROR_RECOVERY BIT_ULL(13)
|
||||
#define BNXT_FW_CAP_PKG_VER BIT_ULL(14)
|
||||
#define BNXT_FW_CAP_CFA_ADV_FLOW BIT_ULL(15)
|
||||
#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2 BIT_ULL(16)
|
||||
#define BNXT_FW_CAP_PCIE_STATS_SUPPORTED BIT_ULL(17)
|
||||
#define BNXT_FW_CAP_EXT_STATS_SUPPORTED BIT_ULL(18)
|
||||
#define BNXT_FW_CAP_SECURE_MODE BIT_ULL(19)
|
||||
#define BNXT_FW_CAP_ERR_RECOVER_RELOAD BIT_ULL(20)
|
||||
#define BNXT_FW_CAP_HOT_RESET BIT_ULL(21)
|
||||
#define BNXT_FW_CAP_CRASHDUMP BIT_ULL(23)
|
||||
#define BNXT_FW_CAP_VLAN_RX_STRIP BIT_ULL(24)
|
||||
#define BNXT_FW_CAP_VLAN_TX_INSERT BIT_ULL(25)
|
||||
#define BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED BIT_ULL(26)
|
||||
#define BNXT_FW_CAP_CFA_EEM BIT_ULL(27)
|
||||
#define BNXT_FW_CAP_DBG_QCAPS BIT_ULL(29)
|
||||
#define BNXT_FW_CAP_RING_MONITOR BIT_ULL(30)
|
||||
#define BNXT_FW_CAP_ECN_STATS BIT_ULL(31)
|
||||
#define BNXT_FW_CAP_TRUFLOW BIT_ULL(32)
|
||||
#define BNXT_FW_CAP_VF_CFG_FOR_PF BIT_ULL(33)
|
||||
#define BNXT_FW_CAP_PTP_PPS BIT_ULL(34)
|
||||
#define BNXT_FW_CAP_HOT_RESET_IF BIT_ULL(35)
|
||||
#define BNXT_FW_CAP_LIVEPATCH BIT_ULL(36)
|
||||
#define BNXT_FW_CAP_NPAR_1_2 BIT_ULL(37)
|
||||
#define BNXT_FW_CAP_RSS_HASH_TYPE_DELTA BIT_ULL(38)
|
||||
#define BNXT_FW_CAP_PTP_RTC BIT_ULL(39)
|
||||
#define BNXT_FW_CAP_TRUFLOW_EN BIT_ULL(40)
|
||||
#define BNXT_TRUFLOW_EN(bp) ((bp)->fw_cap & BNXT_FW_CAP_TRUFLOW_EN)
|
||||
#define BNXT_FW_CAP_RX_ALL_PKT_TS BIT_ULL(41)
|
||||
#define BNXT_FW_CAP_BACKING_STORE_V2 BIT_ULL(42)
|
||||
#define BNXT_FW_CAP_DBR_SUPPORTED BIT_ULL(43)
|
||||
#define BNXT_FW_CAP_GENERIC_STATS BIT_ULL(44)
|
||||
#define BNXT_FW_CAP_DBR_PACING_SUPPORTED BIT_ULL(45)
|
||||
#define BNXT_FW_CAP_PTP_PTM BIT_ULL(46)
|
||||
#define BNXT_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO BIT_ULL(47)
|
||||
#define BNXT_FW_CAP_ENABLE_RDMA_SRIOV BIT_ULL(48)
|
||||
#define BNXT_FW_CAP_RSS_TCAM BIT_ULL(49)
|
||||
uint32_t lpi_tmr_lo;
|
||||
uint32_t lpi_tmr_hi;
|
||||
/* copied from flags and flags2 in hwrm_port_phy_qcaps_output */
|
||||
uint16_t phy_flags;
|
||||
#define BNXT_PHY_FL_EEE_CAP HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_EEE_SUPPORTED
|
||||
#define BNXT_PHY_FL_EXT_LPBK HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_EXTERNAL_LPBK_SUPPORTED
|
||||
#define BNXT_PHY_FL_AN_PHY_LPBK HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_AUTONEG_LPBK_SUPPORTED
|
||||
#define BNXT_PHY_FL_SHARED_PORT_CFG HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_SHARED_PHY_CFG_SUPPORTED
|
||||
#define BNXT_PHY_FL_PORT_STATS_NO_RESET HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_CUMULATIVE_COUNTERS_ON_RESET
|
||||
#define BNXT_PHY_FL_NO_PHY_LPBK HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_LOCAL_LPBK_NOT_SUPPORTED
|
||||
#define BNXT_PHY_FL_FW_MANAGED_LKDN HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_FW_MANAGED_LINK_DOWN
|
||||
#define BNXT_PHY_FL_NO_FCS HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_NO_FCS
|
||||
#define BNXT_PHY_FL_NO_PAUSE (HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS2_PAUSE_UNSUPPORTED << 8)
|
||||
#define BNXT_PHY_FL_NO_PFC (HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS2_PFC_UNSUPPORTED << 8)
|
||||
#define BNXT_PHY_FL_BANK_SEL (HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS2_BANK_ADDR_SUPPORTED << 8)
|
||||
};
|
||||
|
||||
struct bnxt_filter_info {
|
||||
|
@ -843,6 +948,17 @@ struct bnxt_softc *bnxt_find_dev(uint32_t domain, uint32_t bus, uint32_t dev_fn,
|
|||
int bnxt_read_sfp_module_eeprom_info(struct bnxt_softc *bp, uint16_t i2c_addr,
|
||||
uint16_t page_number, uint8_t bank, bool bank_sel_en, uint16_t start_addr,
|
||||
uint16_t data_length, uint8_t *buf);
|
||||
void bnxt_dcb_init(struct bnxt_softc *softc);
|
||||
void bnxt_dcb_free(struct bnxt_softc *softc);
|
||||
uint8_t bnxt_dcb_setdcbx(struct bnxt_softc *softc, uint8_t mode);
|
||||
uint8_t bnxt_dcb_getdcbx(struct bnxt_softc *softc);
|
||||
int bnxt_dcb_ieee_getets(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets);
|
||||
int bnxt_dcb_ieee_setets(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets);
|
||||
uint8_t get_phy_type(struct bnxt_softc *softc);
|
||||
int bnxt_dcb_ieee_getpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc);
|
||||
int bnxt_dcb_ieee_setpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc);
|
||||
int bnxt_dcb_ieee_setapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app);
|
||||
int bnxt_dcb_ieee_delapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app);
|
||||
int bnxt_dcb_ieee_listapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs);
|
||||
|
||||
#endif /* _BNXT_H */
|
861
sys/dev/bnxt/bnxt_en/bnxt_dcb.c
Normal file
861
sys/dev/bnxt/bnxt_en/bnxt_dcb.c
Normal file
|
@ -0,0 +1,861 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2024 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/endian.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "bnxt.h"
|
||||
#include "bnxt_hwrm.h"
|
||||
#include "bnxt_dcb.h"
|
||||
#include "hsi_struct_def.h"
|
||||
|
||||
static int
|
||||
bnxt_tx_queue_to_tc(struct bnxt_softc *softc, uint8_t queue_id)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < softc->max_tc; i++) {
|
||||
if (softc->tx_q_info[i].queue_id == queue_id) {
|
||||
for (j = 0; j < softc->max_tc; j++) {
|
||||
if (softc->tc_to_qidx[j] == i)
|
||||
return j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_pri2cos_cfg(struct bnxt_softc *softc,
|
||||
struct bnxt_ieee_ets *ets,
|
||||
uint32_t path_dir)
|
||||
{
|
||||
struct hwrm_queue_pri2cos_cfg_input req = {0};
|
||||
struct bnxt_queue_info *q_info;
|
||||
uint8_t *pri2cos;
|
||||
int i;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_PRI2COS_CFG);
|
||||
|
||||
req.flags = htole32(path_dir | HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_IVLAN);
|
||||
if (path_dir == HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_BIDIR ||
|
||||
path_dir == HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_TX)
|
||||
q_info = softc->tx_q_info;
|
||||
else
|
||||
q_info = softc->rx_q_info;
|
||||
pri2cos = &req.pri0_cos_queue_id;
|
||||
for (i = 0; i < BNXT_IEEE_8021QAZ_MAX_TCS; i++) {
|
||||
uint8_t qidx;
|
||||
|
||||
req.enables |= htole32(HWRM_QUEUE_PRI2COS_CFG_INPUT_ENABLES_PRI0_COS_QUEUE_ID << i);
|
||||
|
||||
qidx = softc->tc_to_qidx[ets->prio_tc[i]];
|
||||
pri2cos[i] = q_info[qidx].queue_id;
|
||||
}
|
||||
return _hwrm_send_message(softc, &req, sizeof(req));
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets)
|
||||
{
|
||||
struct hwrm_queue_pri2cos_qcfg_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct hwrm_queue_pri2cos_qcfg_input req = {0};
|
||||
int rc;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_PRI2COS_QCFG);
|
||||
|
||||
req.flags = htole32(HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_IVLAN);
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
if (!rc) {
|
||||
uint8_t *pri2cos = &resp->pri0_cos_queue_id;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BNXT_IEEE_8021QAZ_MAX_TCS; i++) {
|
||||
uint8_t queue_id = pri2cos[i];
|
||||
int tc;
|
||||
|
||||
tc = bnxt_tx_queue_to_tc(softc, queue_id);
|
||||
if (tc >= 0)
|
||||
ets->prio_tc[i] = tc;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_cos2bw_cfg(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets,
|
||||
uint8_t max_tc)
|
||||
{
|
||||
struct hwrm_queue_cos2bw_cfg_input req = {0};
|
||||
struct bnxt_cos2bw_cfg cos2bw;
|
||||
void *data;
|
||||
int i;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_COS2BW_CFG);
|
||||
|
||||
for (i = 0; i < max_tc; i++) {
|
||||
uint8_t qidx = softc->tc_to_qidx[i];
|
||||
|
||||
req.enables |=
|
||||
htole32(HWRM_QUEUE_COS2BW_CFG_INPUT_ENABLES_COS_QUEUE_ID0_VALID << qidx);
|
||||
|
||||
memset(&cos2bw, 0, sizeof(cos2bw));
|
||||
cos2bw.queue_id = softc->tx_q_info[qidx].queue_id;
|
||||
if (ets->tc_tsa[i] == BNXT_IEEE_8021QAZ_TSA_STRICT) {
|
||||
cos2bw.tsa =
|
||||
HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_TSA_ASSIGN_SP;
|
||||
cos2bw.pri_lvl = i;
|
||||
} else {
|
||||
cos2bw.tsa =
|
||||
HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_TSA_ASSIGN_ETS;
|
||||
cos2bw.bw_weight = ets->tc_tx_bw[i];
|
||||
/* older firmware requires min_bw to be set to the
|
||||
* same weight value in percent.
|
||||
*/
|
||||
if (BNXT_FW_MAJ(softc) < 218) {
|
||||
cos2bw.min_bw =
|
||||
htole32((ets->tc_tx_bw[i] * 100) |
|
||||
BW_VALUE_UNIT_PERCENT1_100);
|
||||
}
|
||||
}
|
||||
data = &req.unused_0 + qidx * (sizeof(cos2bw) - 4);
|
||||
memcpy(data, &cos2bw.queue_id, sizeof(cos2bw) - 4);
|
||||
if (qidx == 0) {
|
||||
req.queue_id0 = cos2bw.queue_id;
|
||||
req.unused_0 = 0;
|
||||
}
|
||||
}
|
||||
return _hwrm_send_message(softc, &req, sizeof(req));
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets)
|
||||
{
|
||||
struct hwrm_queue_cos2bw_qcfg_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct hwrm_queue_cos2bw_qcfg_input req = {0};
|
||||
struct bnxt_cos2bw_cfg cos2bw;
|
||||
uint8_t *data;
|
||||
int rc, i;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_COS2BW_QCFG);
|
||||
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
data = &resp->queue_id0 + offsetof(struct bnxt_cos2bw_cfg, queue_id);
|
||||
for (i = 0; i < softc->max_tc; i++, data += sizeof(cos2bw.cfg)) {
|
||||
int tc;
|
||||
|
||||
memcpy(&cos2bw.cfg, data, sizeof(cos2bw.cfg));
|
||||
if (i == 0)
|
||||
cos2bw.queue_id = resp->queue_id0;
|
||||
|
||||
tc = bnxt_tx_queue_to_tc(softc, cos2bw.queue_id);
|
||||
if (tc < 0)
|
||||
continue;
|
||||
|
||||
if (cos2bw.tsa == HWRM_QUEUE_COS2BW_QCFG_OUTPUT_QUEUE_ID0_TSA_ASSIGN_SP) {
|
||||
ets->tc_tsa[tc] = BNXT_IEEE_8021QAZ_TSA_STRICT;
|
||||
} else {
|
||||
ets->tc_tsa[tc] = BNXT_IEEE_8021QAZ_TSA_ETS;
|
||||
ets->tc_tx_bw[tc] = cos2bw.bw_weight;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_queue_remap(struct bnxt_softc *softc, unsigned int lltc_mask)
|
||||
{
|
||||
unsigned long qmap = 0;
|
||||
int max = softc->max_tc;
|
||||
int i, j, rc;
|
||||
|
||||
/* Assign lossless TCs first */
|
||||
for (i = 0, j = 0; i < max; ) {
|
||||
if (lltc_mask & (1 << i)) {
|
||||
if (BNXT_LLQ(softc->rx_q_info[j].queue_profile)) {
|
||||
softc->tc_to_qidx[i] = j;
|
||||
__set_bit(j, &qmap);
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < max; i++) {
|
||||
if (lltc_mask & (1 << i))
|
||||
continue;
|
||||
j = find_next_zero_bit(&qmap, max, j);
|
||||
softc->tc_to_qidx[i] = j;
|
||||
__set_bit(j, &qmap);
|
||||
j++;
|
||||
}
|
||||
|
||||
if (softc->ieee_ets) {
|
||||
rc = bnxt_hwrm_queue_cos2bw_cfg(softc, softc->ieee_ets, softc->max_tc);
|
||||
if (rc) {
|
||||
device_printf(softc->dev, "failed to config BW, rc = %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
rc = bnxt_hwrm_queue_pri2cos_cfg(softc, softc->ieee_ets,
|
||||
HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_BIDIR);
|
||||
if (rc) {
|
||||
device_printf(softc->dev, "failed to config prio, rc = %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_pfc_cfg(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc)
|
||||
{
|
||||
struct hwrm_queue_pfcenable_cfg_input req = {0};
|
||||
struct bnxt_ieee_ets *my_ets = softc->ieee_ets;
|
||||
unsigned int tc_mask = 0, pri_mask = 0;
|
||||
uint8_t i, pri, lltc_count = 0;
|
||||
bool need_q_remap = false;
|
||||
|
||||
if (!my_ets)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < softc->max_tc; i++) {
|
||||
for (pri = 0; pri < BNXT_IEEE_8021QAZ_MAX_TCS; pri++) {
|
||||
if ((pfc->pfc_en & (1 << pri)) &&
|
||||
(my_ets->prio_tc[pri] == i)) {
|
||||
pri_mask |= 1 << pri;
|
||||
tc_mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
if (tc_mask & (1 << i))
|
||||
lltc_count++;
|
||||
}
|
||||
|
||||
if (lltc_count > softc->max_lltc) {
|
||||
device_printf(softc->dev,
|
||||
"Hardware doesn't support %d lossless queues "
|
||||
"to configure PFC (cap %d)\n", lltc_count, softc->max_lltc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < softc->max_tc; i++) {
|
||||
if (tc_mask & (1 << i)) {
|
||||
uint8_t qidx = softc->tc_to_qidx[i];
|
||||
|
||||
if (!BNXT_LLQ(softc->rx_q_info[qidx].queue_profile)) {
|
||||
need_q_remap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (need_q_remap)
|
||||
bnxt_queue_remap(softc, tc_mask);
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_PFCENABLE_CFG);
|
||||
|
||||
req.flags = htole32(pri_mask);
|
||||
return _hwrm_send_message(softc, &req, sizeof(req));
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_pfc_qcfg(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc)
|
||||
{
|
||||
struct hwrm_queue_pfcenable_qcfg_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct hwrm_queue_pfcenable_qcfg_input req = {0};
|
||||
uint8_t pri_mask;
|
||||
int rc;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_PFCENABLE_QCFG);
|
||||
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
pri_mask = le32toh(resp->flags);
|
||||
pfc->pfc_en = pri_mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_get_dcbx_app(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs)
|
||||
{
|
||||
struct hwrm_fw_get_structured_data_input get = {0};
|
||||
struct hwrm_struct_data_dcbx_app *fw_app;
|
||||
struct hwrm_struct_hdr *data;
|
||||
struct iflib_dma_info dma_data;
|
||||
size_t data_len;
|
||||
int rc, n, i;
|
||||
|
||||
if (softc->hwrm_spec_code < 0x10601)
|
||||
return 0;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &get, HWRM_FW_GET_STRUCTURED_DATA);
|
||||
|
||||
n = BNXT_IEEE_8021QAZ_MAX_TCS;
|
||||
data_len = sizeof(*data) + sizeof(*fw_app) * n;
|
||||
rc = iflib_dma_alloc(softc->ctx, data_len, &dma_data,
|
||||
BUS_DMA_NOWAIT);
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
get.dest_data_addr = htole64(dma_data.idi_paddr);
|
||||
get.structure_id = htole16(HWRM_STRUCT_HDR_STRUCT_ID_DCBX_APP);
|
||||
get.subtype = htole16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
|
||||
get.count = 0;
|
||||
rc = _hwrm_send_message(softc, &get, sizeof(get));
|
||||
if (rc)
|
||||
goto set_app_exit;
|
||||
|
||||
data = (void *)dma_data.idi_vaddr;
|
||||
fw_app = (struct hwrm_struct_data_dcbx_app *)(data + 1);
|
||||
|
||||
if (data->struct_id != htole16(HWRM_STRUCT_HDR_STRUCT_ID_DCBX_APP)) {
|
||||
rc = -ENODEV;
|
||||
goto set_app_exit;
|
||||
}
|
||||
|
||||
n = data->count;
|
||||
for (i = 0; i < n; i++, fw_app++) {
|
||||
app[*num_inputs].priority = fw_app->priority;
|
||||
app[*num_inputs].protocol = htobe16(fw_app->protocol_id);
|
||||
app[*num_inputs].selector = fw_app->protocol_selector;
|
||||
(*num_inputs)++;
|
||||
}
|
||||
|
||||
set_app_exit:
|
||||
iflib_dma_free(&dma_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_set_dcbx_app(struct bnxt_softc *softc, struct bnxt_dcb_app *app,
|
||||
bool add)
|
||||
{
|
||||
struct hwrm_fw_set_structured_data_input set = {0};
|
||||
struct hwrm_fw_get_structured_data_input get = {0};
|
||||
struct hwrm_struct_data_dcbx_app *fw_app;
|
||||
struct hwrm_struct_hdr *data;
|
||||
struct iflib_dma_info dma_data;
|
||||
size_t data_len;
|
||||
int rc, n, i;
|
||||
|
||||
if (softc->hwrm_spec_code < 0x10601)
|
||||
return 0;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &get, HWRM_FW_GET_STRUCTURED_DATA);
|
||||
|
||||
n = BNXT_IEEE_8021QAZ_MAX_TCS;
|
||||
data_len = sizeof(*data) + sizeof(*fw_app) * n;
|
||||
rc = iflib_dma_alloc(softc->ctx, data_len, &dma_data,
|
||||
BUS_DMA_NOWAIT);
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
get.dest_data_addr = htole64(dma_data.idi_paddr);
|
||||
get.structure_id = htole16(HWRM_STRUCT_HDR_STRUCT_ID_DCBX_APP);
|
||||
get.subtype = htole16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
|
||||
get.count = 0;
|
||||
rc = _hwrm_send_message(softc, &get, sizeof(get));
|
||||
if (rc)
|
||||
goto set_app_exit;
|
||||
|
||||
data = (void *)dma_data.idi_vaddr;
|
||||
fw_app = (struct hwrm_struct_data_dcbx_app *)(data + 1);
|
||||
|
||||
if (data->struct_id != htole16(HWRM_STRUCT_HDR_STRUCT_ID_DCBX_APP)) {
|
||||
rc = -ENODEV;
|
||||
goto set_app_exit;
|
||||
}
|
||||
|
||||
n = data->count;
|
||||
for (i = 0; i < n; i++, fw_app++) {
|
||||
if (fw_app->protocol_id == htobe16(app->protocol) &&
|
||||
fw_app->protocol_selector == app->selector &&
|
||||
fw_app->priority == app->priority) {
|
||||
if (add)
|
||||
goto set_app_exit;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (add) {
|
||||
/* append */
|
||||
n++;
|
||||
fw_app->protocol_id = htobe16(app->protocol);
|
||||
fw_app->protocol_selector = app->selector;
|
||||
fw_app->priority = app->priority;
|
||||
fw_app->valid = 1;
|
||||
} else {
|
||||
size_t len = 0;
|
||||
|
||||
/* not found, nothing to delete */
|
||||
if (n == i)
|
||||
goto set_app_exit;
|
||||
|
||||
len = (n - 1 - i) * sizeof(*fw_app);
|
||||
if (len)
|
||||
memmove(fw_app, fw_app + 1, len);
|
||||
n--;
|
||||
memset(fw_app + n, 0, sizeof(*fw_app));
|
||||
}
|
||||
data->count = n;
|
||||
data->len = htole16(sizeof(*fw_app) * n);
|
||||
data->subtype = htole16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &set, HWRM_FW_SET_STRUCTURED_DATA);
|
||||
|
||||
set.src_data_addr = htole64(dma_data.idi_paddr);
|
||||
set.data_len = htole16(sizeof(*data) + sizeof(*fw_app) * n);
|
||||
set.hdr_cnt = 1;
|
||||
rc = _hwrm_send_message(softc, &set, sizeof(set));
|
||||
|
||||
set_app_exit:
|
||||
iflib_dma_free(&dma_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_dscp_qcaps(struct bnxt_softc *softc)
|
||||
{
|
||||
struct hwrm_queue_dscp_qcaps_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct hwrm_queue_dscp_qcaps_input req = {0};
|
||||
int rc;
|
||||
|
||||
softc->max_dscp_value = 0;
|
||||
if (softc->hwrm_spec_code < 0x10800 || BNXT_VF(softc))
|
||||
return 0;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_DSCP_QCAPS);
|
||||
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
if (!rc) {
|
||||
softc->max_dscp_value = (1 << resp->num_dscp_bits) - 1;
|
||||
if (softc->max_dscp_value < 0x3f)
|
||||
softc->max_dscp_value = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_dscp2pri_qcfg(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs)
|
||||
{
|
||||
struct hwrm_queue_dscp2pri_qcfg_input req = {0};
|
||||
struct hwrm_queue_dscp2pri_qcfg_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct bnxt_dscp2pri_entry *dscp2pri;
|
||||
struct iflib_dma_info dma_data;
|
||||
int rc, entry_cnt;
|
||||
int i;
|
||||
|
||||
if (softc->hwrm_spec_code < 0x10800)
|
||||
return 0;
|
||||
|
||||
rc = iflib_dma_alloc(softc->ctx, sizeof(*dscp2pri) * 128, &dma_data,
|
||||
BUS_DMA_NOWAIT);
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
|
||||
dscp2pri = (void *)dma_data.idi_vaddr;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_DSCP2PRI_QCFG);
|
||||
|
||||
req.dest_data_addr = htole64(dma_data.idi_paddr);
|
||||
req.dest_data_buffer_size = htole16(sizeof(*dscp2pri) * 64);
|
||||
req.port_id = htole16(softc->pf.port_id);
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
|
||||
if (rc)
|
||||
goto end;
|
||||
|
||||
entry_cnt = le16toh(resp->entry_cnt);
|
||||
for (i = 0; i < entry_cnt; i++) {
|
||||
app[*num_inputs].priority = dscp2pri[i].pri;
|
||||
app[*num_inputs].protocol = dscp2pri[i].dscp;
|
||||
app[*num_inputs].selector = BNXT_IEEE_8021QAZ_APP_SEL_DSCP;
|
||||
(*num_inputs)++;
|
||||
}
|
||||
|
||||
end:
|
||||
iflib_dma_free(&dma_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt_softc *softc, struct bnxt_dcb_app *app,
|
||||
bool add)
|
||||
{
|
||||
struct hwrm_queue_dscp2pri_cfg_input req = {0};
|
||||
struct bnxt_dscp2pri_entry *dscp2pri;
|
||||
struct iflib_dma_info dma_data;
|
||||
int rc;
|
||||
|
||||
if (softc->hwrm_spec_code < 0x10800)
|
||||
return 0;
|
||||
|
||||
rc = iflib_dma_alloc(softc->ctx, sizeof(*dscp2pri), &dma_data,
|
||||
BUS_DMA_NOWAIT);
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_DSCP2PRI_CFG);
|
||||
|
||||
req.src_data_addr = htole64(dma_data.idi_paddr);
|
||||
dscp2pri = (void *)dma_data.idi_vaddr;
|
||||
dscp2pri->dscp = app->protocol;
|
||||
if (add)
|
||||
dscp2pri->mask = 0x3f;
|
||||
else
|
||||
dscp2pri->mask = 0;
|
||||
dscp2pri->pri = app->priority;
|
||||
req.entry_cnt = htole16(1);
|
||||
req.port_id = htole16(softc->pf.port_id);
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
|
||||
iflib_dma_free(&dma_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_ets_validate(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets, uint8_t *tc)
|
||||
{
|
||||
int total_ets_bw = 0;
|
||||
bool zero = false;
|
||||
uint8_t max_tc = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BNXT_IEEE_8021QAZ_MAX_TCS; i++) {
|
||||
if (ets->prio_tc[i] > softc->max_tc) {
|
||||
device_printf(softc->dev, "priority to TC mapping exceeds TC count %d\n",
|
||||
ets->prio_tc[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ets->prio_tc[i] > max_tc)
|
||||
max_tc = ets->prio_tc[i];
|
||||
|
||||
if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) && i > softc->max_tc)
|
||||
return -EINVAL;
|
||||
|
||||
switch (ets->tc_tsa[i]) {
|
||||
case BNXT_IEEE_8021QAZ_TSA_STRICT:
|
||||
break;
|
||||
case BNXT_IEEE_8021QAZ_TSA_ETS:
|
||||
total_ets_bw += ets->tc_tx_bw[i];
|
||||
zero = zero || !ets->tc_tx_bw[i];
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
}
|
||||
if (total_ets_bw > 100) {
|
||||
device_printf(softc->dev, "rejecting ETS config exceeding available bandwidth\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (zero && total_ets_bw == 100) {
|
||||
device_printf(softc->dev, "rejecting ETS config starving a TC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (max_tc >= softc->max_tc)
|
||||
*tc = softc->max_tc;
|
||||
else
|
||||
*tc = max_tc + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_dcb_ieee_getets(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets)
|
||||
{
|
||||
struct bnxt_ieee_ets *my_ets = softc->ieee_ets;
|
||||
int rc;
|
||||
|
||||
if (!my_ets)
|
||||
return 0;
|
||||
|
||||
rc = bnxt_hwrm_queue_cos2bw_qcfg(softc, my_ets);
|
||||
if (rc)
|
||||
goto error;
|
||||
rc = bnxt_hwrm_queue_pri2cos_qcfg(softc, my_ets);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
if (ets) {
|
||||
ets->cbs = my_ets->cbs;
|
||||
ets->ets_cap = softc->max_tc;
|
||||
memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
|
||||
memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw));
|
||||
memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
|
||||
memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_dcb_ieee_setets(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets)
|
||||
{
|
||||
uint8_t max_tc = 0;
|
||||
int rc;
|
||||
|
||||
if (!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_VER_IEEE) ||
|
||||
!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_HOST))
|
||||
return -EINVAL;
|
||||
|
||||
rc = bnxt_ets_validate(softc, ets, &max_tc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = bnxt_hwrm_queue_cos2bw_cfg(softc, ets, max_tc);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
if (!softc->is_asym_q) {
|
||||
rc = bnxt_hwrm_queue_pri2cos_cfg(softc, ets,
|
||||
HWRM_QUEUE_PRI2COS_CFG_INPUT_FLAGS_PATH_BIDIR);
|
||||
if (rc)
|
||||
goto error;
|
||||
} else {
|
||||
rc = bnxt_hwrm_queue_pri2cos_cfg(softc, ets,
|
||||
HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_TX);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
rc = bnxt_hwrm_queue_pri2cos_cfg(softc, ets,
|
||||
HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_RX);
|
||||
if (rc)
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(softc->ieee_ets, ets, sizeof(*ets));
|
||||
return 0;
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_dcb_ieee_getpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc)
|
||||
{
|
||||
struct bnxt_ieee_pfc *my_pfc = softc->ieee_pfc;
|
||||
int rc;
|
||||
|
||||
if (!my_pfc)
|
||||
return -1;
|
||||
|
||||
pfc->pfc_cap = softc->max_lltc;
|
||||
|
||||
rc = bnxt_hwrm_queue_pfc_qcfg(softc, my_pfc);
|
||||
if (rc)
|
||||
return 0;
|
||||
|
||||
pfc->pfc_en = my_pfc->pfc_en;
|
||||
pfc->mbc = my_pfc->mbc;
|
||||
pfc->delay = my_pfc->delay;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_dcb_ieee_setpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc)
|
||||
{
|
||||
struct bnxt_ieee_pfc *my_pfc = softc->ieee_pfc;
|
||||
int rc;
|
||||
|
||||
if (!my_pfc)
|
||||
return -1;
|
||||
|
||||
if (!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_VER_IEEE) ||
|
||||
!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_HOST) ||
|
||||
(softc->phy_flags & BNXT_PHY_FL_NO_PAUSE))
|
||||
return -EINVAL;
|
||||
|
||||
rc = bnxt_hwrm_queue_pfc_cfg(softc, pfc);
|
||||
if (!rc)
|
||||
memcpy(my_pfc, pfc, sizeof(*my_pfc));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_dcb_ieee_dscp_app_prep(struct bnxt_softc *softc, struct bnxt_dcb_app *app)
|
||||
{
|
||||
if (app->selector == BNXT_IEEE_8021QAZ_APP_SEL_DSCP) {
|
||||
if (!softc->max_dscp_value)
|
||||
return -ENOTSUPP;
|
||||
if (app->protocol > softc->max_dscp_value)
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_dcb_ieee_setapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
||||
if (!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_VER_IEEE) ||
|
||||
!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_HOST))
|
||||
return -EINVAL;
|
||||
|
||||
rc = bnxt_dcb_ieee_dscp_app_prep(softc, app);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if ((app->selector == BNXT_IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
|
||||
app->protocol == ETH_P_ROCE) ||
|
||||
(app->selector == BNXT_IEEE_8021QAZ_APP_SEL_DGRAM &&
|
||||
app->protocol == ROCE_V2_UDP_DPORT))
|
||||
rc = bnxt_hwrm_set_dcbx_app(softc, app, true);
|
||||
|
||||
if (app->selector == BNXT_IEEE_8021QAZ_APP_SEL_DSCP)
|
||||
rc = bnxt_hwrm_queue_dscp2pri_cfg(softc, app, true);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_dcb_ieee_delapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_VER_IEEE) ||
|
||||
!(softc->dcbx_cap & BNXT_DCB_CAP_DCBX_HOST))
|
||||
return -EINVAL;
|
||||
|
||||
rc = bnxt_dcb_ieee_dscp_app_prep(softc, app);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if ((app->selector == BNXT_IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
|
||||
app->protocol == ETH_P_ROCE) ||
|
||||
(app->selector == BNXT_IEEE_8021QAZ_APP_SEL_DGRAM &&
|
||||
app->protocol == ROCE_V2_UDP_DPORT))
|
||||
rc = bnxt_hwrm_set_dcbx_app(softc, app, false);
|
||||
|
||||
if (app->selector == BNXT_IEEE_8021QAZ_APP_SEL_DSCP)
|
||||
rc = bnxt_hwrm_queue_dscp2pri_cfg(softc, app, false);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_dcb_ieee_listapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs)
|
||||
{
|
||||
bnxt_hwrm_get_dcbx_app(softc, app, num_inputs);
|
||||
bnxt_hwrm_queue_dscp2pri_qcfg(softc, app, num_inputs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
bnxt_dcb_getdcbx(struct bnxt_softc *softc)
|
||||
{
|
||||
return softc->dcbx_cap;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
bnxt_dcb_setdcbx(struct bnxt_softc *softc, uint8_t mode)
|
||||
{
|
||||
/* All firmware DCBX settings are set in NVRAM */
|
||||
if (softc->dcbx_cap & BNXT_DCB_CAP_DCBX_LLD_MANAGED)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Do't allow editing CAP_DCBX_LLD_MANAGED since it is driven
|
||||
* based on FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED
|
||||
*/
|
||||
if ((softc->dcbx_cap & BNXT_DCB_CAP_DCBX_LLD_MANAGED) !=
|
||||
(mode & BNXT_DCB_CAP_DCBX_LLD_MANAGED))
|
||||
return 1;
|
||||
|
||||
if (mode & BNXT_DCB_CAP_DCBX_HOST) {
|
||||
if (BNXT_VF(softc) || (softc->fw_cap & BNXT_FW_CAP_LLDP_AGENT))
|
||||
return 1;
|
||||
|
||||
/* only support BNXT_IEEE */
|
||||
if ((mode & BNXT_DCB_CAP_DCBX_VER_CEE) ||
|
||||
!(mode & BNXT_DCB_CAP_DCBX_VER_IEEE))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mode == softc->dcbx_cap)
|
||||
return 0;
|
||||
|
||||
softc->dcbx_cap = mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bnxt_dcb_init(struct bnxt_softc *softc)
|
||||
{
|
||||
struct bnxt_ieee_ets ets = {0};
|
||||
struct bnxt_ieee_pfc pfc = {0};
|
||||
|
||||
softc->dcbx_cap = 0;
|
||||
|
||||
if (softc->hwrm_spec_code < 0x10501)
|
||||
return;
|
||||
|
||||
softc->ieee_ets = malloc(sizeof(struct bnxt_ieee_ets), M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (!softc->ieee_ets)
|
||||
return;
|
||||
|
||||
softc->ieee_pfc = malloc(sizeof(struct bnxt_ieee_pfc), M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (!softc->ieee_pfc)
|
||||
return;
|
||||
|
||||
bnxt_hwrm_queue_dscp_qcaps(softc);
|
||||
softc->dcbx_cap = BNXT_DCB_CAP_DCBX_VER_IEEE;
|
||||
if (BNXT_PF(softc) && !(softc->fw_cap & BNXT_FW_CAP_LLDP_AGENT))
|
||||
softc->dcbx_cap |= BNXT_DCB_CAP_DCBX_HOST;
|
||||
else if (softc->fw_cap & BNXT_FW_CAP_DCBX_AGENT)
|
||||
softc->dcbx_cap |= BNXT_DCB_CAP_DCBX_LLD_MANAGED;
|
||||
|
||||
bnxt_dcb_ieee_setets(softc, &ets);
|
||||
bnxt_dcb_ieee_setpfc(softc, &pfc);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
bnxt_dcb_free(struct bnxt_softc *softc)
|
||||
{
|
||||
free(softc->ieee_ets, M_DEVBUF);
|
||||
softc->ieee_ets = NULL;
|
||||
free(softc->ieee_pfc, M_DEVBUF);
|
||||
softc->ieee_pfc = NULL;
|
||||
}
|
127
sys/dev/bnxt/bnxt_en/bnxt_dcb.h
Normal file
127
sys/dev/bnxt/bnxt_en/bnxt_dcb.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*-
|
||||
* Broadcom NetXtreme-C/E network driver.
|
||||
*
|
||||
* Copyright (c) 2024 Broadcom, All Rights Reserved.
|
||||
* The term Broadcom refers to Broadcom Limited and/or its subsidiaries
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BNXT_DCB_H
|
||||
#define _BNXT_DCB_H
|
||||
|
||||
#define BNXT_IEEE_8021QAZ_MAX_TCS 8
|
||||
#define BNXT_IEEE_8021QAZ_TSA_STRICT 0
|
||||
#define BNXT_IEEE_8021QAZ_TSA_ETS 2
|
||||
#define BNXT_IEEE_8021QAZ_TSA_VENDOR 255
|
||||
|
||||
#define BNXT_DCB_CAP_DCBX_HOST 0x01
|
||||
#define BNXT_DCB_CAP_DCBX_LLD_MANAGED 0x02
|
||||
#define BNXT_DCB_CAP_DCBX_VER_CEE 0x04
|
||||
#define BNXT_DCB_CAP_DCBX_VER_IEEE 0x08
|
||||
#define BNXT_DCB_CAP_DCBX_STATIC 0x10
|
||||
|
||||
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
|
||||
union { \
|
||||
struct { MEMBERS } ATTRS; \
|
||||
struct TAG { MEMBERS } ATTRS NAME; \
|
||||
}
|
||||
#define struct_group_attr(NAME, ATTRS, MEMBERS...) \
|
||||
__struct_group(/* no tag */, NAME, ATTRS, MEMBERS)
|
||||
|
||||
struct bnxt_cos2bw_cfg {
|
||||
uint8_t pad[3];
|
||||
struct_group_attr(cfg, __packed,
|
||||
uint8_t queue_id;
|
||||
uint32_t min_bw;
|
||||
uint32_t max_bw;
|
||||
#define BW_VALUE_UNIT_PERCENT1_100 (0x1UL << 29)
|
||||
uint8_t tsa;
|
||||
uint8_t pri_lvl;
|
||||
uint8_t bw_weight;
|
||||
);
|
||||
uint8_t unused;
|
||||
};
|
||||
|
||||
struct bnxt_dscp2pri_entry {
|
||||
uint8_t dscp;
|
||||
uint8_t mask;
|
||||
uint8_t pri;
|
||||
};
|
||||
|
||||
struct bnxt_ieee_ets {
|
||||
uint8_t willing;
|
||||
uint8_t ets_cap;
|
||||
uint8_t cbs;
|
||||
uint8_t tc_tx_bw[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
uint8_t tc_rx_bw[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
uint8_t tc_tsa[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
uint8_t prio_tc[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
uint8_t tc_reco_bw[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
uint8_t tc_reco_tsa[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
uint8_t reco_prio_tc[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct bnxt_ieee_pfc {
|
||||
uint8_t pfc_cap;
|
||||
uint8_t pfc_en;
|
||||
uint8_t mbc;
|
||||
uint16_t delay;
|
||||
uint64_t requests[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
uint64_t indications[BNXT_IEEE_8021QAZ_MAX_TCS];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct bnxt_dcb_app {
|
||||
uint8_t selector;
|
||||
uint8_t priority;
|
||||
uint16_t protocol;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct bnxt_eee {
|
||||
uint32_t cmd;
|
||||
uint32_t supported;
|
||||
uint32_t advertised;
|
||||
uint32_t lp_advertised;
|
||||
uint32_t eee_active;
|
||||
uint32_t eee_enabled;
|
||||
uint32_t tx_lpi_enabled;
|
||||
uint32_t tx_lpi_timer;
|
||||
uint32_t reserved[2];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define BNXT_IEEE_8021QAZ_APP_SEL_ETHERTYPE 1
|
||||
#define BNXT_IEEE_8021QAZ_APP_SEL_STREAM 2
|
||||
#define BNXT_IEEE_8021QAZ_APP_SEL_DGRAM 3
|
||||
#define BNXT_IEEE_8021QAZ_APP_SEL_ANY 4
|
||||
#define BNXT_IEEE_8021QAZ_APP_SEL_DSCP 5
|
||||
#define ETH_P_ROCE 0x8915
|
||||
#define ROCE_V2_UDP_DPORT 4791
|
||||
|
||||
#define BNXT_LLQ(q_profile) \
|
||||
((q_profile) == HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS_ROCE || \
|
||||
(q_profile) == HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS_NIC)
|
||||
#define BNXT_CNPQ(q_profile) \
|
||||
((q_profile) == HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY_ROCE_CNP)
|
||||
|
||||
#define HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL 0x0300
|
||||
|
||||
#endif
|
|
@ -42,9 +42,6 @@ static void bnxt_hwrm_set_pause_common(struct bnxt_softc *softc,
|
|||
struct hwrm_port_phy_cfg_input *req);
|
||||
static void bnxt_hwrm_set_eee(struct bnxt_softc *softc,
|
||||
struct hwrm_port_phy_cfg_input *req);
|
||||
static int _hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
|
||||
static int hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
|
||||
static void bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *, void *, uint16_t);
|
||||
|
||||
/* NVRam stuff has a five minute timeout */
|
||||
#define BNXT_NVM_TIMEO (5 * 60 * 1000)
|
||||
|
@ -97,7 +94,7 @@ bnxt_free_hwrm_dma_mem(struct bnxt_softc *softc)
|
|||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *softc, void *request,
|
||||
uint16_t req_type)
|
||||
{
|
||||
|
@ -109,7 +106,7 @@ bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *softc, void *request,
|
|||
req->resp_addr = htole64(softc->hwrm_cmd_resp.idi_paddr);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
_hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
|
||||
{
|
||||
struct input *req = msg;
|
||||
|
@ -222,7 +219,7 @@ _hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
|
||||
{
|
||||
int rc;
|
||||
|
@ -234,13 +231,16 @@ hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
|
|||
}
|
||||
|
||||
int
|
||||
bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc)
|
||||
bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc, uint32_t path_dir)
|
||||
{
|
||||
int rc = 0;
|
||||
struct hwrm_queue_qportcfg_input req = {0};
|
||||
struct hwrm_queue_qportcfg_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
uint8_t i, j, *qptr;
|
||||
uint8_t max_tc, max_lltc, *max_q;
|
||||
uint8_t queue_profile, queue_id;
|
||||
struct bnxt_queue_info *q_info;
|
||||
uint8_t i, j, *qptr, *q_ids;
|
||||
bool no_rdma;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_QPORTCFG);
|
||||
|
@ -254,29 +254,56 @@ bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc)
|
|||
rc = -EINVAL;
|
||||
goto qportcfg_exit;
|
||||
}
|
||||
softc->max_tc = resp->max_configurable_queues;
|
||||
softc->max_lltc = resp->max_configurable_lossless_queues;
|
||||
if (softc->max_tc > BNXT_MAX_COS_QUEUE)
|
||||
softc->max_tc = BNXT_MAX_COS_QUEUE;
|
||||
|
||||
/* Currently no RDMA support */
|
||||
if (resp->queue_cfg_info & HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG) {
|
||||
softc->is_asym_q = true;
|
||||
/* bnxt_init_cosq_names(softc, path_dir); */
|
||||
} else {
|
||||
softc->is_asym_q = false;
|
||||
/* bnxt_free_stats_cosqnames_mem(softc); */
|
||||
}
|
||||
|
||||
max_tc = min_t(uint8_t, resp->max_configurable_queues, BNXT_MAX_QUEUE);
|
||||
max_lltc = resp->max_configurable_lossless_queues;
|
||||
|
||||
/*
|
||||
* No RDMA support yet.
|
||||
* no_rdma = !(softc->flags & BNXT_FLAG_ROCE_CAP);
|
||||
*/
|
||||
no_rdma = true;
|
||||
|
||||
qptr = &resp->queue_id0;
|
||||
for (i = 0, j = 0; i < softc->max_tc; i++) {
|
||||
softc->q_info[j].id = *qptr;
|
||||
softc->q_ids[i] = *qptr++;
|
||||
softc->q_info[j].profile = *qptr++;
|
||||
|
||||
if (path_dir == HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX) {
|
||||
q_info = softc->tx_q_info;
|
||||
q_ids = softc->tx_q_ids;
|
||||
max_q = &softc->tx_max_q;
|
||||
} else {
|
||||
q_info = softc->rx_q_info;
|
||||
q_ids = softc->rx_q_ids;
|
||||
max_q = &softc->rx_max_q;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < max_tc; i++) {
|
||||
queue_id = *qptr;
|
||||
qptr++;
|
||||
|
||||
queue_profile = *qptr;
|
||||
qptr++;
|
||||
|
||||
q_info[j].queue_id = queue_id;
|
||||
q_info[j].queue_profile = queue_profile;
|
||||
q_ids[i] = queue_id;
|
||||
|
||||
softc->tc_to_qidx[j] = j;
|
||||
if (!BNXT_CNPQ(softc->q_info[j].profile) ||
|
||||
(no_rdma && BNXT_PF(softc)))
|
||||
|
||||
if (!BNXT_CNPQ(q_info[j].queue_profile) ||
|
||||
(no_rdma && BNXT_PF(softc)))
|
||||
j++;
|
||||
}
|
||||
softc->max_q = softc->max_tc;
|
||||
softc->max_tc = max_t(uint32_t, j, 1);
|
||||
|
||||
if (resp->queue_cfg_info & HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG)
|
||||
softc->max_tc = 1;
|
||||
*max_q = max_tc;
|
||||
max_tc = max_t(uint8_t, j, 1);
|
||||
softc->max_tc = softc->max_tc ? min(softc->max_tc, max_tc) : max_tc;
|
||||
softc->max_lltc = softc->max_lltc ? min(softc->max_lltc, max_lltc) : max_lltc;
|
||||
|
||||
if (softc->max_lltc > softc->max_tc)
|
||||
softc->max_lltc = softc->max_tc;
|
||||
|
@ -309,14 +336,14 @@ int bnxt_hwrm_func_backing_store_qcaps(struct bnxt_softc *softc)
|
|||
rc = -ENOMEM;
|
||||
goto ctx_err;
|
||||
}
|
||||
ctx_pg = malloc(sizeof(*ctx_pg) * (softc->max_q + 1),
|
||||
ctx_pg = malloc(sizeof(*ctx_pg) * (softc->rx_max_q + 1),
|
||||
M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (!ctx_pg) {
|
||||
free(ctx, M_DEVBUF);
|
||||
rc = -ENOMEM;
|
||||
goto ctx_err;
|
||||
}
|
||||
for (i = 0; i < softc->max_q + 1; i++, ctx_pg++)
|
||||
for (i = 0; i < softc->rx_max_q + 1; i++, ctx_pg++)
|
||||
ctx->tqm_mem[i] = ctx_pg;
|
||||
|
||||
softc->ctx_mem = ctx;
|
||||
|
@ -669,6 +696,7 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
|
|||
len = BC_HWRM_STR_LEN;
|
||||
}
|
||||
|
||||
softc->ver_info->fw_ver_code = BNXT_FW_VER_CODE(fw_maj, fw_min, fw_bld, fw_rsv);
|
||||
snprintf (softc->ver_info->fw_ver_str, len, "%d.%d.%d.%d",
|
||||
fw_maj, fw_min, fw_bld, fw_rsv);
|
||||
|
||||
|
@ -678,6 +706,7 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
|
|||
snprintf(softc->ver_info->fw_ver_str + fw_ver_len,
|
||||
FW_VER_STR_LEN - fw_ver_len - 1, "/pkg %s",
|
||||
resp->active_pkg_name);
|
||||
softc->fw_cap |= BNXT_FW_CAP_PKG_VER;
|
||||
}
|
||||
|
||||
softc->ver_info->chip_num = le16toh(resp->chip_num);
|
||||
|
@ -695,12 +724,33 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
|
|||
if (!softc->hwrm_cmd_timeo)
|
||||
softc->hwrm_cmd_timeo = DFLT_HWRM_CMD_TIMEOUT;
|
||||
|
||||
|
||||
dev_caps_cfg = le32toh(resp->dev_caps_cfg);
|
||||
if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
|
||||
(dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
|
||||
softc->flags |= BNXT_FLAG_SHORT_CMD;
|
||||
|
||||
if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
|
||||
(dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
|
||||
softc->fw_cap |= BNXT_FW_CAP_SHORT_CMD;
|
||||
|
||||
if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_KONG_MB_CHNL_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_KONG_MB_CHNL;
|
||||
|
||||
if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FLOW_HANDLE_64BIT_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_OVS_64BIT_HANDLE;
|
||||
|
||||
if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_TRUSTED_VF_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_TRUSTED_VF;
|
||||
|
||||
if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_CFA_ADV_FLOW_MGNT_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_CFA_ADV_FLOW;
|
||||
|
||||
if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_CFA_EEM_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_CFA_EEM;
|
||||
|
||||
if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_CFA_TRUFLOW_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_TRUFLOW_EN;
|
||||
|
||||
fail:
|
||||
BNXT_HWRM_UNLOCK(softc);
|
||||
return rc;
|
||||
|
@ -766,6 +816,7 @@ bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
|
|||
struct hwrm_func_qcaps_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct bnxt_func_info *func = &softc->func;
|
||||
uint32_t flags, flags_ext, flags_ext2;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCAPS);
|
||||
req.fid = htole16(0xffff);
|
||||
|
@ -775,13 +826,70 @@ bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
|
|||
if (rc)
|
||||
goto fail;
|
||||
|
||||
if (resp->flags &
|
||||
htole32(HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED))
|
||||
flags = htole32(resp->flags);
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED)
|
||||
softc->flags |= BNXT_FLAG_WOL_CAP;
|
||||
if (resp->flags &
|
||||
htole32(HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED))
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED)
|
||||
softc->flags |= BNXT_FLAG_FW_CAP_EXT_STATS;
|
||||
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_LINK_ADMIN_STATUS_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_LINK_ADMIN;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ADMIN_PF_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_ADMIN_PF;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_HOT_RESET_CAPABLE)
|
||||
softc->fw_cap |= BNXT_FW_CAP_HOT_RESET;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERROR_RECOVERY_CAPABLE)
|
||||
softc->fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PCIE_STATS_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_PCIE_STATS_SUPPORTED;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD)
|
||||
softc->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_NOTIFY_VF_DEF_VNIC_CHNG_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_VF_VNIC_NOTIFY;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_CRASHDUMP_CMD_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_CRASHDUMP;
|
||||
if (!(flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VLAN_ACCELERATION_TX_DISABLED))
|
||||
softc->fw_cap |= BNXT_FW_CAP_VLAN_TX_INSERT;
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_DBG_QCAPS_CMD_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_DBG_QCAPS;
|
||||
|
||||
flags_ext = htole32(resp->flags_ext);
|
||||
if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_EXT_HW_STATS_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED;
|
||||
if (BNXT_PF(softc) && (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_ECN_STATS_SUPPORTED))
|
||||
softc->fw_cap |= BNXT_FW_CAP_ECN_STATS;
|
||||
|
||||
if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_PTP_PPS_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_PTP_PPS;
|
||||
if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_PTP_PTM_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_PTP_PTM;
|
||||
if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_PTP_64BIT_RTC_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_PTP_RTC;
|
||||
if (BNXT_PF(softc) && (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_HOT_RESET_IF_SUPPORT))
|
||||
softc->fw_cap |= BNXT_FW_CAP_HOT_RESET_IF;
|
||||
if (BNXT_PF(softc) && (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_FW_LIVEPATCH_SUPPORTED))
|
||||
softc->fw_cap |= BNXT_FW_CAP_LIVEPATCH;
|
||||
if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_NPAR_1_2_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_NPAR_1_2;
|
||||
if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_BS_V2_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_BACKING_STORE_V2;
|
||||
if (BNXT_PF(softc) &&
|
||||
(flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_VF_CFG_ASYNC_FOR_PF_SUPPORTED))
|
||||
softc->fw_cap |= BNXT_FW_CAP_VF_CFG_FOR_PF;
|
||||
|
||||
flags_ext2 = htole32(resp->flags_ext2);
|
||||
if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_RX_ALL_PKTS_TIMESTAMPS_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_RX_ALL_PKT_TS;
|
||||
if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_SW_DBR_DROP_RECOVERY_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_DBR_SUPPORTED;
|
||||
if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_DBR_PACING_EXT_SUPPORTED ||
|
||||
flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_DBR_PACING_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_DBR_PACING_SUPPORTED;
|
||||
|
||||
if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_GENERIC_STATS_SUPPORTED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_GENERIC_STATS;
|
||||
func->fw_fid = le16toh(resp->fid);
|
||||
memcpy(func->mac_addr, resp->mac_address, ETHER_ADDR_LEN);
|
||||
func->max_rsscos_ctxs = le16toh(resp->max_rsscos_ctx);
|
||||
|
@ -820,26 +928,45 @@ bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
|
|||
int
|
||||
bnxt_hwrm_func_qcfg(struct bnxt_softc *softc)
|
||||
{
|
||||
struct hwrm_func_qcfg_input req = {0};
|
||||
struct hwrm_func_qcfg_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct hwrm_func_qcfg_input req = {0};
|
||||
struct hwrm_func_qcfg_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
struct bnxt_func_qcfg *fn_qcfg = &softc->fn_qcfg;
|
||||
int rc;
|
||||
uint16_t flags;
|
||||
int rc;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCFG);
|
||||
req.fid = htole16(0xffff);
|
||||
req.fid = htole16(0xffff);
|
||||
BNXT_HWRM_LOCK(softc);
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
if (rc)
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
fn_qcfg->alloc_completion_rings = le16toh(resp->alloc_cmpl_rings);
|
||||
fn_qcfg->alloc_tx_rings = le16toh(resp->alloc_tx_rings);
|
||||
fn_qcfg->alloc_rx_rings = le16toh(resp->alloc_rx_rings);
|
||||
fn_qcfg->alloc_vnics = le16toh(resp->alloc_vnics);
|
||||
|
||||
flags = le16toh(resp->flags);
|
||||
if (flags & (HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED |
|
||||
HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED)) {
|
||||
softc->fw_cap |= BNXT_FW_CAP_LLDP_AGENT;
|
||||
if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
|
||||
}
|
||||
if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST))
|
||||
softc->flags |= BNXT_FLAG_MULTI_HOST;
|
||||
if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_ROOT))
|
||||
softc->flags |= BNXT_FLAG_MULTI_ROOT;
|
||||
if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_SECURE_MODE_ENABLED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_SECURE_MODE;
|
||||
if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_RING_MONITOR_ENABLED)
|
||||
softc->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
|
||||
if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_ENABLE_RDMA_SRIOV)
|
||||
softc->fw_cap |= BNXT_FW_CAP_ENABLE_RDMA_SRIOV;
|
||||
fail:
|
||||
BNXT_HWRM_UNLOCK(softc);
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1282,48 +1409,48 @@ bnxt_hwrm_ring_alloc(struct bnxt_softc *softc, uint8_t type,
|
|||
req.length = htole32(ring->ring_size);
|
||||
|
||||
switch (type) {
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
|
||||
cp_ring = &softc->tx_cp_rings[idx];
|
||||
|
||||
req.cmpl_ring_id = htole16(cp_ring->ring.phys_id);
|
||||
req.cmpl_ring_id = htole16(cp_ring->ring.phys_id);
|
||||
/* queue_id - what CoS queue the TX ring is associated with */
|
||||
req.queue_id = htole16(softc->q_info[0].id);
|
||||
req.queue_id = htole16(softc->tx_q_info[0].queue_id);
|
||||
|
||||
req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
|
||||
req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
|
||||
req.enables |= htole32(
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX:
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX:
|
||||
if (!BNXT_CHIP_P5(softc))
|
||||
break;
|
||||
|
||||
cp_ring = &softc->rx_cp_rings[idx];
|
||||
|
||||
req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
|
||||
req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
|
||||
req.rx_buf_size = htole16(softc->rx_buf_size);
|
||||
req.enables |= htole32(
|
||||
req.enables |= htole32(
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID |
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG:
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG:
|
||||
if (!BNXT_CHIP_P5(softc)) {
|
||||
req.ring_type = HWRM_RING_ALLOC_INPUT_RING_TYPE_RX;
|
||||
req.ring_type = HWRM_RING_ALLOC_INPUT_RING_TYPE_RX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cp_ring = &softc->rx_cp_rings[idx];
|
||||
|
||||
req.rx_ring_id = htole16(softc->rx_rings[idx].phys_id);
|
||||
req.rx_ring_id = htole16(softc->rx_rings[idx].phys_id);
|
||||
req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
|
||||
req.rx_buf_size = htole16(softc->rx_buf_size);
|
||||
req.enables |= htole32(
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_RX_RING_ID_VALID |
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID |
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
|
||||
req.enables |= htole32(
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_RX_RING_ID_VALID |
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID |
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
|
||||
if (!BNXT_CHIP_P5(softc)) {
|
||||
req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
|
||||
req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1331,14 +1458,15 @@ bnxt_hwrm_ring_alloc(struct bnxt_softc *softc, uint8_t type,
|
|||
req.nq_ring_id = htole16(softc->nq_rings[idx].ring.phys_id);
|
||||
req.enables |= htole32(
|
||||
HWRM_RING_ALLOC_INPUT_ENABLES_NQ_RING_ID_VALID);
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ:
|
||||
req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
|
||||
break;
|
||||
default:
|
||||
printf("hwrm alloc invalid ring type %d\n", type);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ:
|
||||
req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
|
||||
break;
|
||||
default:
|
||||
device_printf(softc->dev,
|
||||
"hwrm alloc invalid ring type %d\n", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BNXT_HWRM_LOCK(softc);
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
|
@ -2251,9 +2379,9 @@ bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc)
|
|||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
int rc = 0;
|
||||
|
||||
BNXT_HWRM_LOCK(softc);
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_QCFG);
|
||||
|
||||
BNXT_HWRM_LOCK(softc);
|
||||
rc = _hwrm_send_message(softc, &req, sizeof(req));
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
@ -2366,6 +2494,15 @@ int bnxt_hwrm_phy_qcaps(struct bnxt_softc *softc)
|
|||
if (rc)
|
||||
goto exit;
|
||||
|
||||
softc->phy_flags = resp->flags | (resp->flags2 << 8);
|
||||
if (resp->flags & HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_EEE_SUPPORTED) {
|
||||
|
||||
softc->lpi_tmr_lo = le32toh(resp->tx_lpi_timer_low) &
|
||||
HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_LOW_MASK;
|
||||
softc->lpi_tmr_hi = le32toh(resp->valid_tx_lpi_timer_high) &
|
||||
HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_HIGH_MASK;
|
||||
}
|
||||
|
||||
if (softc->hwrm_spec_code >= 0x10a01) {
|
||||
if (bnxt_phy_qcaps_no_speed(resp)) {
|
||||
link_info->phy_state = BNXT_PHY_STATE_DISABLED;
|
||||
|
@ -2473,80 +2610,82 @@ static void bnxt_hwrm_set_coal_params(struct bnxt_softc *softc, uint32_t max_fra
|
|||
|
||||
int bnxt_hwrm_set_coal(struct bnxt_softc *softc)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0},
|
||||
req_tx = {0}, *req;
|
||||
uint16_t max_buf, max_buf_irq;
|
||||
uint16_t buf_tmr, buf_tmr_irq;
|
||||
uint32_t flags;
|
||||
int i, rc = 0;
|
||||
struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0},
|
||||
req_tx = {0}, *req;
|
||||
uint16_t max_buf, max_buf_irq;
|
||||
uint16_t buf_tmr, buf_tmr_irq;
|
||||
uint32_t flags;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req_rx,
|
||||
HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req_tx,
|
||||
HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req_rx,
|
||||
HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req_tx,
|
||||
HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
|
||||
|
||||
/* Each rx completion (2 records) should be DMAed immediately.
|
||||
* DMA 1/4 of the completion buffers at a time.
|
||||
*/
|
||||
max_buf = min_t(uint16_t, softc->rx_coal_frames / 4, 2);
|
||||
/* max_buf must not be zero */
|
||||
max_buf = clamp_t(uint16_t, max_buf, 1, 63);
|
||||
max_buf_irq = clamp_t(uint16_t, softc->rx_coal_frames_irq, 1, 63);
|
||||
buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs);
|
||||
/* buf timer set to 1/4 of interrupt timer */
|
||||
buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
|
||||
buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs_irq);
|
||||
buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
|
||||
/* Each rx completion (2 records) should be DMAed immediately.
|
||||
* DMA 1/4 of the completion buffers at a time.
|
||||
*/
|
||||
max_buf = min_t(uint16_t, softc->rx_coal_frames / 4, 2);
|
||||
/* max_buf must not be zero */
|
||||
max_buf = clamp_t(uint16_t, max_buf, 1, 63);
|
||||
max_buf_irq = clamp_t(uint16_t, softc->rx_coal_frames_irq, 1, 63);
|
||||
buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs);
|
||||
/* buf timer set to 1/4 of interrupt timer */
|
||||
buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
|
||||
buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs_irq);
|
||||
buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
|
||||
|
||||
flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
|
||||
flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
|
||||
|
||||
/* RING_IDLE generates more IRQs for lower latency. Enable it only
|
||||
* if coal_usecs is less than 25 us.
|
||||
*/
|
||||
if (softc->rx_coal_usecs < 25)
|
||||
flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE;
|
||||
/* RING_IDLE generates more IRQs for lower latency. Enable it only
|
||||
* if coal_usecs is less than 25 us.
|
||||
*/
|
||||
if (softc->rx_coal_usecs < 25)
|
||||
flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE;
|
||||
|
||||
bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
|
||||
buf_tmr_irq << 16 | buf_tmr, flags, &req_rx);
|
||||
bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
|
||||
buf_tmr_irq << 16 | buf_tmr, flags, &req_rx);
|
||||
|
||||
/* max_buf must not be zero */
|
||||
max_buf = clamp_t(uint16_t, softc->tx_coal_frames, 1, 63);
|
||||
max_buf_irq = clamp_t(uint16_t, softc->tx_coal_frames_irq, 1, 63);
|
||||
buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs);
|
||||
/* buf timer set to 1/4 of interrupt timer */
|
||||
buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
|
||||
buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs_irq);
|
||||
buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
|
||||
flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
|
||||
bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
|
||||
buf_tmr_irq << 16 | buf_tmr, flags, &req_tx);
|
||||
/* max_buf must not be zero */
|
||||
max_buf = clamp_t(uint16_t, softc->tx_coal_frames, 1, 63);
|
||||
max_buf_irq = clamp_t(uint16_t, softc->tx_coal_frames_irq, 1, 63);
|
||||
buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs);
|
||||
/* buf timer set to 1/4 of interrupt timer */
|
||||
buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
|
||||
buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs_irq);
|
||||
buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
|
||||
flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
|
||||
bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
|
||||
buf_tmr_irq << 16 | buf_tmr, flags, &req_tx);
|
||||
|
||||
for (i = 0; i < softc->nrxqsets; i++) {
|
||||
for (i = 0; i < softc->nrxqsets; i++) {
|
||||
|
||||
req = &req_rx;
|
||||
/*
|
||||
* TBD:
|
||||
/*
|
||||
* TBD:
|
||||
* Check if Tx also needs to be done
|
||||
* So far, Tx processing has been done in softirq contest
|
||||
*
|
||||
* So far, Tx processing has been done in softirq contest
|
||||
*
|
||||
* req = &req_tx;
|
||||
*/
|
||||
req->ring_id = htole16(softc->grp_info[i].cp_ring_id);
|
||||
|
||||
rc = hwrm_send_message(softc, req, sizeof(*req));
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
rc = hwrm_send_message(softc, req, sizeof(*req));
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc, unsigned long *bmap,
|
||||
int bmap_size)
|
||||
int bmap_size)
|
||||
{
|
||||
struct hwrm_func_drv_rgtr_input req = {0};
|
||||
struct hwrm_func_drv_rgtr_output *resp =
|
||||
(void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
bitstr_t *async_events_bmap;
|
||||
uint32_t *events;
|
||||
int i;
|
||||
int i, rc = 0;
|
||||
|
||||
#define BNXT_MAX_NUM_ASYNC_EVENTS 256
|
||||
async_events_bmap = bit_alloc(BNXT_MAX_NUM_ASYNC_EVENTS, M_DEVBUF,
|
||||
|
@ -2578,15 +2717,22 @@ int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc, unsigned long *bm
|
|||
|
||||
free(async_events_bmap, M_DEVBUF);
|
||||
|
||||
return hwrm_send_message(softc, &req, sizeof(req));
|
||||
rc = hwrm_send_message(softc, &req, sizeof(req));
|
||||
if (!rc) {
|
||||
if (resp->flags &
|
||||
le32toh(HWRM_FUNC_DRV_RGTR_OUTPUT_FLAGS_IF_CHANGE_SUPPORTED))
|
||||
softc->fw_cap |= BNXT_FW_CAP_IF_CHANGE;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void bnxt_hwrm_ring_info_get(struct bnxt_softc *softc, uint8_t ring_type,
|
||||
uint32_t ring_id, uint32_t *prod, uint32_t *cons)
|
||||
uint32_t ring_id, uint32_t *prod, uint32_t *cons)
|
||||
{
|
||||
hwrm_dbg_ring_info_get_input_t req = {0};
|
||||
hwrm_dbg_ring_info_get_output_t *resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
int rc = 0;
|
||||
hwrm_dbg_ring_info_get_input_t req = {0};
|
||||
hwrm_dbg_ring_info_get_output_t *resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
|
||||
int rc = 0;
|
||||
|
||||
*prod = *cons = 0xffffffff;
|
||||
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_DBG_RING_INFO_GET);
|
|
@ -45,7 +45,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt_softc *softc, uint8_t type,
|
|||
int bnxt_hwrm_ring_free(struct bnxt_softc *softc, uint32_t type,
|
||||
struct bnxt_ring *ring, int cmpl_ring_id);
|
||||
int bnxt_hwrm_ver_get(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc, uint32_t path_dir);
|
||||
int bnxt_hwrm_func_drv_rgtr(struct bnxt_softc *softc);
|
||||
int bnxt_hwrm_func_drv_unrgtr(struct bnxt_softc *softc, bool shutdown);
|
||||
int bnxt_hwrm_func_qcaps(struct bnxt_softc *softc);
|
||||
|
@ -128,7 +128,10 @@ int bnxt_hwrm_func_backing_store_cfg(struct bnxt_softc *softc, uint32_t);
|
|||
int bnxt_hwrm_func_resc_qcaps(struct bnxt_softc *softc, bool all);
|
||||
int bnxt_hwrm_reserve_pf_rings (struct bnxt_softc *softc);
|
||||
void bnxt_hwrm_ring_info_get(struct bnxt_softc *softc, uint8_t ring_type,
|
||||
uint32_t ring_id, uint32_t *prod, uint32_t *);
|
||||
uint32_t ring_id, uint32_t *prod, uint32_t *);
|
||||
int bnxt_hwrm_passthrough(struct bnxt_softc *softc, void *req, uint32_t req_len,
|
||||
void *resp, uint32_t resp_len, uint32_t timeout);
|
||||
int _hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
|
||||
int hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
|
||||
void bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *, void *, uint16_t);
|
||||
#endif
|
|
@ -95,6 +95,70 @@ bnxt_mgmt_loader(struct module *m, int what, void *arg)
|
|||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_mgmt_process_dcb(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
int flag, struct thread *td)
|
||||
{
|
||||
struct bnxt_softc *softc = NULL;
|
||||
struct bnxt_mgmt_dcb mgmt_dcb = {};
|
||||
void *user_ptr;
|
||||
int ret = 0;
|
||||
|
||||
memcpy(&user_ptr, data, sizeof(user_ptr));
|
||||
if (copyin(user_ptr, &mgmt_dcb, sizeof(mgmt_dcb))) {
|
||||
printf("%s: %s:%d Failed to copy data from user\n",
|
||||
DRIVER_NAME, __FUNCTION__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
softc = bnxt_find_dev(mgmt_dcb.hdr.domain, mgmt_dcb.hdr.bus,
|
||||
mgmt_dcb.hdr.devfn, NULL);
|
||||
if (!softc) {
|
||||
printf("%s: %s:%d unable to find softc reference\n",
|
||||
DRIVER_NAME, __FUNCTION__, __LINE__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (mgmt_dcb.op) {
|
||||
case BNXT_MGMT_DCB_GET_ETS:
|
||||
bnxt_dcb_ieee_getets(softc, &mgmt_dcb.req.ets);
|
||||
break;
|
||||
case BNXT_MGMT_DCB_SET_ETS:
|
||||
bnxt_dcb_ieee_setets(softc, &mgmt_dcb.req.ets);
|
||||
break;
|
||||
case BNXT_MGMT_DCB_GET_PFC:
|
||||
bnxt_dcb_ieee_getpfc(softc, &mgmt_dcb.req.pfc);
|
||||
break;
|
||||
case BNXT_MGMT_DCB_SET_PFC:
|
||||
bnxt_dcb_ieee_setpfc(softc, &mgmt_dcb.req.pfc);
|
||||
break;
|
||||
case BNXT_MGMT_DCB_SET_APP:
|
||||
bnxt_dcb_ieee_setapp(softc, &mgmt_dcb.req.app_tlv.app[0]);
|
||||
break;
|
||||
case BNXT_MGMT_DCB_DEL_APP:
|
||||
bnxt_dcb_ieee_delapp(softc, &mgmt_dcb.req.app_tlv.app[0]);
|
||||
break;
|
||||
case BNXT_MGMT_DCB_LIST_APP:
|
||||
bnxt_dcb_ieee_listapp(softc, &mgmt_dcb.req.app_tlv.app[0],
|
||||
&mgmt_dcb.req.app_tlv.num_app);
|
||||
break;
|
||||
default:
|
||||
device_printf(softc->dev, "%s:%d Invalid op 0x%x\n",
|
||||
__FUNCTION__, __LINE__, mgmt_dcb.op);
|
||||
ret = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (copyout(&mgmt_dcb, user_ptr, sizeof(mgmt_dcb))) {
|
||||
device_printf(softc->dev, "%s:%d Failed to copy response to user\n",
|
||||
__FUNCTION__, __LINE__);
|
||||
ret = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
int flag, struct thread *td)
|
||||
|
@ -345,9 +409,12 @@ bnxt_mgmt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
|||
break;
|
||||
case BNXT_MGMT_OPCODE_PASSTHROUGH_HWRM:
|
||||
mtx_lock(&mgmt_lock);
|
||||
ret = bnxt_mgmt_process_hwrm(dev, cmd, data, flag, td);
|
||||
ret = bnxt_mgmt_process_hwrm(dev, cmd, data, flag, td);
|
||||
mtx_unlock(&mgmt_lock);
|
||||
break;
|
||||
case BNXT_MGMT_OPCODE_DCB_OPS:
|
||||
ret = bnxt_mgmt_process_dcb(dev, cmd, data, flag, td);
|
||||
break;
|
||||
default:
|
||||
printf("%s: Unknown command 0x%lx\n", DRIVER_NAME, cmd);
|
||||
ret = -EINVAL;
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#define BNXT_MGMT_OPCODE_GET_DEV_INFO 0x80000000
|
||||
#define BNXT_MGMT_OPCODE_PASSTHROUGH_HWRM 0x80000001
|
||||
#define BNXT_MGMT_OPCODE_DCB_OPS 0x80000002
|
||||
|
||||
#define BNXT_MGMT_MAX_HWRM_REQ_LENGTH HWRM_MAX_REQ_LEN
|
||||
#define BNXT_MGMT_MAX_HWRM_RESP_LENGTH (512)
|
||||
|
@ -118,9 +119,31 @@ struct bnxt_mgmt_req_hdr {
|
|||
};
|
||||
|
||||
struct bnxt_mgmt_req {
|
||||
struct bnxt_mgmt_req_hdr hdr;
|
||||
union {
|
||||
uint64_t hreq;
|
||||
} req;
|
||||
struct bnxt_mgmt_req_hdr hdr;
|
||||
union {
|
||||
uint64_t hreq;
|
||||
} req;
|
||||
};
|
||||
|
||||
struct bnxt_mgmt_app_tlv {
|
||||
uint32_t num_app;
|
||||
struct bnxt_dcb_app app[128];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct bnxt_mgmt_dcb {
|
||||
struct bnxt_mgmt_req_hdr hdr;
|
||||
#define BNXT_MGMT_DCB_GET_ETS 0x1
|
||||
#define BNXT_MGMT_DCB_SET_ETS 0x2
|
||||
#define BNXT_MGMT_DCB_GET_PFC 0x3
|
||||
#define BNXT_MGMT_DCB_SET_PFC 0x4
|
||||
#define BNXT_MGMT_DCB_SET_APP 0x5
|
||||
#define BNXT_MGMT_DCB_DEL_APP 0x6
|
||||
#define BNXT_MGMT_DCB_LIST_APP 0x7
|
||||
#define BNXT_MGMT_DCB_MAX BNXT_MGMT_DCB_LIST_APP
|
||||
uint32_t op;
|
||||
union {
|
||||
struct bnxt_ieee_ets ets;
|
||||
struct bnxt_ieee_pfc pfc;
|
||||
struct bnxt_mgmt_app_tlv app_tlv;
|
||||
} req;
|
||||
} __attribute__ ((__packed__));
|
|
@ -105,6 +105,16 @@ bnxt_init_sysctl_ctx(struct bnxt_softc *softc)
|
|||
return ENOMEM;
|
||||
}
|
||||
|
||||
sysctl_ctx_init(&softc->dcb_ctx);
|
||||
ctx = device_get_sysctl_ctx(softc->dev);
|
||||
softc->dcb_oid = SYSCTL_ADD_NODE(ctx,
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO,
|
||||
"dcb", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "dcb");
|
||||
if (!softc->dcb_oid) {
|
||||
sysctl_ctx_free(&softc->dcb_ctx);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -151,6 +161,14 @@ bnxt_free_sysctl_ctx(struct bnxt_softc *softc)
|
|||
softc->flow_ctrl_oid = NULL;
|
||||
}
|
||||
|
||||
if (softc->dcb_oid != NULL) {
|
||||
orc = sysctl_ctx_free(&softc->dcb_ctx);
|
||||
if (orc)
|
||||
rc = orc;
|
||||
else
|
||||
softc->dcb_oid = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1460,34 +1478,38 @@ bnxt_create_config_sysctls_pre(struct bnxt_softc *softc)
|
|||
SYSCTL_ADD_CONST_STRING(ctx, children, OID_AUTO, "if_name", CTLFLAG_RD,
|
||||
if_name(iflib_get_ifp(softc->ctx)), "interface name");
|
||||
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_usecs",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_usecs",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_rx_usecs, "I", "interrupt coalescing Rx Usecs");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_frames",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_frames",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_rx_frames, "I", "interrupt coalescing Rx Frames");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_usecs_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_usecs_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_rx_usecs_irq, "I",
|
||||
"interrupt coalescing Rx Usecs IRQ");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_frames_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_rx_frames_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_rx_frames_irq, "I",
|
||||
"interrupt coalescing Rx Frames IRQ");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_usecs",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_usecs",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_tx_usecs, "I", "interrupt coalescing Tx Usces");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_frames",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_tx_frames, "I", "interrupt coalescing Tx Frames");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_usecs_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_frames",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_tx_frames, "I", "interrupt coalescing Tx Frames");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_usecs_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_tx_usecs_irq, "I",
|
||||
"interrupt coalescing Tx Usecs IRQ");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_frames_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
"interrupt coalescing Tx Usecs IRQ");
|
||||
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_frames_irq",
|
||||
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
|
||||
bnxt_set_coal_tx_frames_irq, "I",
|
||||
"interrupt coalescing Tx Frames IRQ");
|
||||
SYSCTL_ADD_U32(ctx, children, OID_AUTO, "flags", CTLFLAG_RD,
|
||||
&softc->flags, 0, "flags");
|
||||
SYSCTL_ADD_U64(ctx, children, OID_AUTO, "fw_cap", CTLFLAG_RD,
|
||||
&softc->fw_cap, 0, "FW caps");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1618,6 +1640,377 @@ bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_dcb_dcbx_cap(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
int val;
|
||||
int rc;
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
val = bnxt_dcb_getdcbx(softc);
|
||||
rc = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (rc || !req->newptr)
|
||||
return rc;
|
||||
|
||||
bnxt_dcb_setdcbx(softc, val);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static char
|
||||
bnxt_ets_tsa_to_str(struct bnxt_softc *softc, uint32_t tc)
|
||||
{
|
||||
switch (softc->ieee_ets->tc_tsa[tc]) {
|
||||
case BNXT_IEEE_8021QAZ_TSA_STRICT:
|
||||
return 's';
|
||||
case BNXT_IEEE_8021QAZ_TSA_ETS:
|
||||
return 'e';
|
||||
default:
|
||||
return 'X';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
bnxt_ets_str_to_tsa(char tsa_str)
|
||||
{
|
||||
switch (tsa_str) {
|
||||
case 's':
|
||||
return BNXT_IEEE_8021QAZ_TSA_STRICT;
|
||||
case 'e':
|
||||
return BNXT_IEEE_8021QAZ_TSA_ETS;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_ets_get_val(struct bnxt_softc *softc, uint32_t type, uint32_t tc)
|
||||
{
|
||||
switch (type) {
|
||||
case BNXT_TYPE_ETS_TSA:
|
||||
if (softc->ieee_ets)
|
||||
return softc->ieee_ets->tc_tsa[tc];
|
||||
break;
|
||||
case BNXT_TYPE_ETS_PRI2TC:
|
||||
if (softc->ieee_ets)
|
||||
return softc->ieee_ets->prio_tc[tc];
|
||||
break;
|
||||
case BNXT_TYPE_ETS_TCBW:
|
||||
if (softc->ieee_ets)
|
||||
return softc->ieee_ets->tc_tx_bw[tc];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
bnxt_pfc_get_string(struct bnxt_softc *softc, char *buf, struct bnxt_ieee_pfc *pfc)
|
||||
{
|
||||
uint32_t i;
|
||||
bool found = false;
|
||||
|
||||
for (i = 0; i < BNXT_IEEE_8021QAZ_MAX_TCS; i++) {
|
||||
if (pfc->pfc_en & (1 << i)) {
|
||||
if (found)
|
||||
buf += sprintf(buf, ", ");
|
||||
buf += sprintf(buf, "%d", i);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
buf += sprintf(buf, "none");
|
||||
}
|
||||
|
||||
static char *bnxt_get_tlv_selector_str(uint8_t selector)
|
||||
{
|
||||
switch (selector) {
|
||||
case BNXT_IEEE_8021QAZ_APP_SEL_ETHERTYPE:
|
||||
return "Ethertype";
|
||||
case BNXT_IEEE_8021QAZ_APP_SEL_DGRAM:
|
||||
return "UDP or DCCP";
|
||||
case BNXT_IEEE_8021QAZ_APP_SEL_DSCP:
|
||||
return "DSCP";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bnxt_app_tlv_get_string(struct bnxt_softc *softc, char *buf,
|
||||
struct bnxt_dcb_app *app, int num)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (!num) {
|
||||
buf += sprintf(buf, " None");
|
||||
return;
|
||||
}
|
||||
|
||||
buf += sprintf(buf, "\n");
|
||||
for (i = 0; i < num; i++) {
|
||||
buf += sprintf(buf, "\tAPP#%0d:\tpri: %d,\tSel: %d,\t%s: %d\n",
|
||||
i,
|
||||
app[i].priority,
|
||||
app[i].selector,
|
||||
bnxt_get_tlv_selector_str(app[i].selector),
|
||||
app[i].protocol);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bnxt_ets_get_string(struct bnxt_softc *softc, char *buf)
|
||||
{
|
||||
uint32_t type, i;
|
||||
|
||||
type = BNXT_TYPE_ETS_TSA;
|
||||
for (type = 0; type < BNXT_TYPE_ETS_MAX; type++) {
|
||||
for (i = 0; i < BNXT_IEEE_8021QAZ_MAX_TCS; i++) {
|
||||
if (i == 0)
|
||||
buf += sprintf(buf, "%s:", BNXT_ETS_TYPE_STR[type]);
|
||||
|
||||
if (!softc->ieee_ets)
|
||||
buf += sprintf(buf, "x");
|
||||
else if (type == BNXT_TYPE_ETS_TSA)
|
||||
buf += sprintf(buf, "%c", bnxt_ets_tsa_to_str(softc, i));
|
||||
else
|
||||
buf += sprintf(buf, "%d", bnxt_ets_get_val(softc, type, i));
|
||||
|
||||
if (i != BNXT_IEEE_8021QAZ_MAX_TCS - 1)
|
||||
buf += sprintf(buf, ",");
|
||||
}
|
||||
if (type != BNXT_TYPE_ETS_MAX - 1)
|
||||
buf += sprintf(buf, "#");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_dcb_list_app(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_dcb_app app[128] = {0};
|
||||
struct bnxt_softc *softc = arg1;
|
||||
int rc, num_inputs = 0;
|
||||
char *buf;
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
#define BNXT_APP_TLV_STR_LEN 4096
|
||||
buf = malloc(BNXT_APP_TLV_STR_LEN, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (!buf)
|
||||
return ENOMEM;
|
||||
|
||||
bnxt_dcb_ieee_listapp(softc, app, &num_inputs);
|
||||
bnxt_app_tlv_get_string(softc, buf, app, num_inputs);
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, BNXT_APP_TLV_STR_LEN, req);
|
||||
if (rc || req->newptr == NULL)
|
||||
goto end;
|
||||
|
||||
end:
|
||||
free(buf, M_DEVBUF);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_dcb_del_app(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
struct bnxt_dcb_app app = {0};
|
||||
char buf[256] = {0};
|
||||
int rc, num_inputs;
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (rc || req->newptr == NULL)
|
||||
return rc;
|
||||
|
||||
num_inputs = sscanf(buf, "%hhu,%hhu,%hd", &app.priority, &app.selector, &app.protocol);
|
||||
|
||||
if (num_inputs != 3) {
|
||||
device_printf(softc->dev,
|
||||
"Invalid app tlv syntax, inputs = %d\n", num_inputs);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
bnxt_dcb_ieee_delapp(softc, &app);
|
||||
|
||||
return rc;
|
||||
}
|
||||
static int
|
||||
bnxt_dcb_set_app(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
struct bnxt_dcb_app app = {0};
|
||||
char buf[256] = {0};
|
||||
int rc, num_inputs;
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (rc || req->newptr == NULL)
|
||||
return rc;
|
||||
|
||||
num_inputs = sscanf(buf, "%hhu,%hhu,%hd", &app.priority, &app.selector, &app.protocol);
|
||||
|
||||
if (num_inputs != 3) {
|
||||
device_printf(softc->dev,
|
||||
"Invalid app tlv syntax, inputs = %d\n", num_inputs);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
bnxt_dcb_ieee_setapp(softc, &app);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_dcb_pfc(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
struct bnxt_ieee_pfc pfc = {0};
|
||||
int rc, i, num_inputs;
|
||||
char buf[256] = {0};
|
||||
int pri_mask = 0;
|
||||
char pri[8];
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
rc = bnxt_dcb_ieee_getpfc(softc, &pfc);
|
||||
if (!rc)
|
||||
bnxt_pfc_get_string(softc, buf, &pfc);
|
||||
else
|
||||
sprintf(buf, "## getpfc failed with error %d ##", rc);
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (rc || req->newptr == NULL)
|
||||
return rc;
|
||||
|
||||
/* Check for 'none' string first */
|
||||
if (sscanf(buf, "%s", buf) == 1) {
|
||||
if (strncmp(buf, "none", 8) == 0) {
|
||||
goto configure;
|
||||
}
|
||||
}
|
||||
num_inputs = sscanf(buf, "%hhu,%hhu,%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",
|
||||
&pri[0], &pri[1], &pri[2], &pri[3], &pri[4],
|
||||
&pri[5], &pri[6], &pri[7]);
|
||||
|
||||
if (num_inputs < 1 || num_inputs > 8) {
|
||||
device_printf(softc->dev,
|
||||
"Invalid pfc syntax, inputs = %d\n", num_inputs);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_inputs; i++) {
|
||||
if (pri[i] > 7 || pri[i] < 0) {
|
||||
device_printf(softc->dev,
|
||||
"Invalid priority %d. Valid priorties are "
|
||||
"from 0 to 7 and string \"none\".\n", pri[i]);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
pri_mask |= (1 << pri[i]) & 0xFF;
|
||||
}
|
||||
|
||||
configure:
|
||||
pfc.pfc_en = pri_mask;
|
||||
rc = bnxt_dcb_ieee_setpfc(softc, &pfc);
|
||||
if (rc)
|
||||
device_printf(softc->dev,
|
||||
"setpfc failed with status %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
bnxt_dcb_ets(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct bnxt_softc *softc = arg1;
|
||||
struct bnxt_ieee_ets ets = {0};
|
||||
int rc = 0, i, num_inputs;
|
||||
char buf[256] = {0};
|
||||
char tsa[8];
|
||||
|
||||
if (softc == NULL)
|
||||
return EBUSY;
|
||||
|
||||
rc = bnxt_dcb_ieee_getets(softc, &ets);
|
||||
if (!rc)
|
||||
bnxt_ets_get_string(softc, buf);
|
||||
else
|
||||
sprintf(buf, "## getets failed with error %d ##", rc);
|
||||
|
||||
rc = sysctl_handle_string(oidp, buf, sizeof(buf), req);
|
||||
if (rc || req->newptr == NULL)
|
||||
return rc;
|
||||
|
||||
num_inputs = sscanf(buf, "tsa:%c,%c,%c,%c,%c,%c,%c,%c#"
|
||||
"pri2tc:%hhu,%hhu,%hhu,%hhu,%hhu,%hhu,%hhu,%hhu#"
|
||||
"tcbw:%hhu,%hhu,%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",
|
||||
&tsa[0], &tsa[1], &tsa[2], &tsa[3], &tsa[4], &tsa[5], &tsa[6], &tsa[7],
|
||||
&ets.prio_tc[0], &ets.prio_tc[1], &ets.prio_tc[2], &ets.prio_tc[3],
|
||||
&ets.prio_tc[4], &ets.prio_tc[5], &ets.prio_tc[6], &ets.prio_tc[7],
|
||||
&ets.tc_tx_bw[0], &ets.tc_tx_bw[1], &ets.tc_tx_bw[2], &ets.tc_tx_bw[3],
|
||||
&ets.tc_tx_bw[4], &ets.tc_tx_bw[5], &ets.tc_tx_bw[6], &ets.tc_tx_bw[7]);
|
||||
|
||||
if (num_inputs != 24)
|
||||
return EINVAL;
|
||||
|
||||
for ( i= 0; i < 8; i++)
|
||||
ets.tc_tsa[i] = bnxt_ets_str_to_tsa(tsa[i]);
|
||||
|
||||
rc = bnxt_dcb_ieee_setets(softc, &ets);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_dcb_sysctls(struct bnxt_softc *softc)
|
||||
{
|
||||
struct sysctl_oid *oid = softc->dcb_oid;
|
||||
|
||||
if (!oid)
|
||||
return ENOMEM;
|
||||
|
||||
SYSCTL_ADD_PROC(&softc->dcb_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
|
||||
"dcbx_cap", CTLTYPE_INT | CTLFLAG_RWTUN, softc,
|
||||
0, bnxt_dcb_dcbx_cap, "A",
|
||||
"Enable or Disable LRO: 0 / 1");
|
||||
|
||||
SYSCTL_ADD_PROC(&softc->dcb_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "ets",
|
||||
CTLTYPE_STRING | CTLFLAG_RWTUN, softc, 0,
|
||||
bnxt_dcb_ets, "A", "Enhanced Transmission Selection (ETS)");
|
||||
|
||||
SYSCTL_ADD_PROC(&softc->dcb_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "pfc",
|
||||
CTLTYPE_STRING | CTLFLAG_RWTUN, softc, 0,
|
||||
bnxt_dcb_pfc, "A", "Enhanced Transmission Selection (ETS)");
|
||||
|
||||
SYSCTL_ADD_PROC(&softc->dcb_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "set_apptlv",
|
||||
CTLTYPE_STRING | CTLFLAG_WR, softc, 0,
|
||||
bnxt_dcb_set_app, "A", "Set App TLV");
|
||||
|
||||
SYSCTL_ADD_PROC(&softc->dcb_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "del_apptlv",
|
||||
CTLTYPE_STRING | CTLFLAG_WR, softc, 0,
|
||||
bnxt_dcb_del_app, "A", "Delete App TLV");
|
||||
|
||||
SYSCTL_ADD_PROC(&softc->dcb_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "list_apptlv",
|
||||
CTLTYPE_STRING | CTLFLAG_RD, softc, 0,
|
||||
bnxt_dcb_list_app, "A", "List all App TLVs");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bnxt_create_config_sysctls_post(struct bnxt_softc *softc)
|
||||
{
|
|
@ -40,3 +40,5 @@ int bnxt_create_config_sysctls_pre(struct bnxt_softc *softc);
|
|||
int bnxt_create_config_sysctls_post(struct bnxt_softc *softc);
|
||||
int bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc);
|
||||
int bnxt_create_pause_fc_sysctls(struct bnxt_softc *softc);
|
||||
int bnxt_create_dcb_sysctls(struct bnxt_softc *softc);
|
||||
int bnxt_create_dcb_ets_sysctls(struct bnxt_softc *softc);
|
|
@ -965,7 +965,7 @@ static void bnxt_free_ctx_mem(struct bnxt_softc *softc)
|
|||
return;
|
||||
|
||||
if (ctx->tqm_mem[0]) {
|
||||
for (i = 0; i < softc->max_q + 1; i++) {
|
||||
for (i = 0; i < softc->rx_max_q + 1; i++) {
|
||||
if (!ctx->tqm_mem[i])
|
||||
continue;
|
||||
bnxt_free_ctx_pg_tbls(softc, ctx->tqm_mem[i]);
|
||||
|
@ -1078,7 +1078,7 @@ static int bnxt_alloc_ctx_mem(struct bnxt_softc *softc)
|
|||
entries = roundup(entries, ctx->tqm_entries_multiple);
|
||||
entries = clamp_t(uint32_t, entries, ctx->tqm_min_entries_per_ring,
|
||||
ctx->tqm_max_entries_per_ring);
|
||||
for (i = 0; i < softc->max_q + 1; i++) {
|
||||
for (i = 0; i < softc->rx_max_q + 1; i++) {
|
||||
ctx_pg = ctx->tqm_mem[i];
|
||||
ctx_pg->entries = entries;
|
||||
mem_size = ctx->tqm_entry_size * entries;
|
||||
|
@ -1261,6 +1261,23 @@ struct bnxt_softc *bnxt_find_dev(uint32_t domain, uint32_t bus, uint32_t dev_fn,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void bnxt_verify_asym_queues(struct bnxt_softc *softc)
|
||||
{
|
||||
uint8_t i, lltc = 0;
|
||||
|
||||
if (!softc->max_lltc)
|
||||
return;
|
||||
|
||||
/* Verify that lossless TX and RX queues are in the same index */
|
||||
for (i = 0; i < softc->max_tc; i++) {
|
||||
if (BNXT_LLQ(softc->tx_q_info[i].queue_profile) &&
|
||||
BNXT_LLQ(softc->rx_q_info[i].queue_profile))
|
||||
lltc++;
|
||||
}
|
||||
softc->max_lltc = min(softc->max_lltc, lltc);
|
||||
}
|
||||
|
||||
/* Device setup and teardown */
|
||||
static int
|
||||
bnxt_attach_pre(if_ctx_t ctx)
|
||||
|
@ -1361,12 +1378,10 @@ bnxt_attach_pre(if_ctx_t ctx)
|
|||
|
||||
softc->flags |= BNXT_FLAG_TPA;
|
||||
|
||||
/* No TPA for Thor A0 */
|
||||
if (BNXT_CHIP_P5(softc) && (!softc->ver_info->chip_rev) &&
|
||||
(!softc->ver_info->chip_metal))
|
||||
softc->flags &= ~BNXT_FLAG_TPA;
|
||||
|
||||
/* TBD ++ Add TPA support from Thor B1 */
|
||||
if (BNXT_CHIP_P5(softc))
|
||||
softc->flags &= ~BNXT_FLAG_TPA;
|
||||
|
||||
|
@ -1414,11 +1429,24 @@ bnxt_attach_pre(if_ctx_t ctx)
|
|||
}
|
||||
|
||||
/* Get the queue config */
|
||||
rc = bnxt_hwrm_queue_qportcfg(softc);
|
||||
rc = bnxt_hwrm_queue_qportcfg(softc, HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX);
|
||||
if (rc) {
|
||||
device_printf(softc->dev, "attach: hwrm qportcfg failed\n");
|
||||
device_printf(softc->dev, "attach: hwrm qportcfg (tx) failed\n");
|
||||
goto failed;
|
||||
}
|
||||
if (softc->is_asym_q) {
|
||||
rc = bnxt_hwrm_queue_qportcfg(softc,
|
||||
HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX);
|
||||
if (rc) {
|
||||
device_printf(softc->dev, "attach: hwrm qportcfg (rx) failed\n");
|
||||
return rc;
|
||||
}
|
||||
bnxt_verify_asym_queues(softc);
|
||||
} else {
|
||||
softc->rx_max_q = softc->tx_max_q;
|
||||
memcpy(softc->rx_q_info, softc->tx_q_info, sizeof(softc->rx_q_info));
|
||||
memcpy(softc->rx_q_ids, softc->tx_q_ids, sizeof(softc->rx_q_ids));
|
||||
}
|
||||
|
||||
if (softc->hwrm_spec_code >= 0x10803) {
|
||||
rc = bnxt_alloc_ctx_mem(softc);
|
||||
|
@ -1581,6 +1609,10 @@ bnxt_attach_pre(if_ctx_t ctx)
|
|||
if (rc)
|
||||
goto failed;
|
||||
|
||||
rc = bnxt_create_dcb_sysctls(softc);
|
||||
if (rc)
|
||||
goto failed;
|
||||
|
||||
/* Initialize the vlan list */
|
||||
SLIST_INIT(&softc->vnic_info.vlan_tags);
|
||||
softc->vnic_info.vlan_tag_list.idi_vaddr = NULL;
|
||||
|
@ -1856,7 +1888,6 @@ bnxt_init(if_ctx_t ctx)
|
|||
softc->is_dev_init = true;
|
||||
bnxt_clear_ids(softc);
|
||||
|
||||
// TBD -- Check if it is needed for Thor as well
|
||||
if (BNXT_CHIP_P5(softc))
|
||||
goto skip_def_cp_ring;
|
||||
/* Allocate the default completion ring */
|
||||
|
@ -2001,6 +2032,7 @@ bnxt_init(if_ctx_t ctx)
|
|||
bnxt_get_port_module_status(softc);
|
||||
bnxt_media_status(softc->ctx, &ifmr);
|
||||
bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info);
|
||||
bnxt_dcb_init(softc);
|
||||
return;
|
||||
|
||||
fail:
|
||||
|
@ -2015,6 +2047,7 @@ bnxt_stop(if_ctx_t ctx)
|
|||
struct bnxt_softc *softc = iflib_get_softc(ctx);
|
||||
|
||||
softc->is_dev_init = false;
|
||||
bnxt_dcb_free(softc);
|
||||
bnxt_do_disable_intr(&softc->def_cp_ring);
|
||||
bnxt_func_reset(softc);
|
||||
bnxt_clear_ids(softc);
|
||||
|
@ -2985,6 +3018,7 @@ bnxt_probe_phy(struct bnxt_softc *softc)
|
|||
struct bnxt_link_info *link_info = &softc->link_info;
|
||||
int rc = 0;
|
||||
|
||||
softc->phy_flags = 0;
|
||||
rc = bnxt_hwrm_phy_qcaps(softc);
|
||||
if (rc) {
|
||||
device_printf(softc->dev,
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
.PATH: ${SRCTOP}/sys/dev/bnxt
|
||||
.PATH: ${SRCTOP}/sys/dev/bnxt/bnxt_en
|
||||
|
||||
KMOD = if_bnxt
|
||||
SRCS = device_if.h bus_if.h pci_if.h pci_iov_if.h ifdi_if.h
|
||||
|
@ -8,7 +8,9 @@ SRCS += bnxt_txrx.c if_bnxt.c
|
|||
SRCS += bnxt_hwrm.c
|
||||
SRCS += bnxt_sysctl.c
|
||||
SRCS += bnxt_mgmt.c
|
||||
SRCS += bnxt_dcb.c bnxt_dcb.h
|
||||
|
||||
CFLAGS+= -DIFLIB
|
||||
CFLAGS+= -I${SRCTOP}/sys/compat/linuxkpi/common/include
|
||||
|
||||
.include <bsd.kmod.mk>
|
Loading…
Reference in a new issue