#define BNXT_DEVARG_FLOW_XSTAT "flow-xstat"
#define BNXT_DEVARG_MAX_NUM_KFLOWS "max-num-kflows"
#define BNXT_DEVARG_REPRESENTOR "representor"
+#define BNXT_DEVARG_REP_BASED_PF "rep-based-pf"
+#define BNXT_DEVARG_REP_IS_PF "rep-is-pf"
+#define BNXT_DEVARG_REP_Q_R2F "rep-q-r2f"
+#define BNXT_DEVARG_REP_Q_F2R "rep-q-f2r"
+#define BNXT_DEVARG_REP_FC_R2F "rep-fc-r2f"
+#define BNXT_DEVARG_REP_FC_F2R "rep-fc-f2r"
static const char *const bnxt_dev_args[] = {
BNXT_DEVARG_REPRESENTOR,
BNXT_DEVARG_TRUFLOW,
BNXT_DEVARG_FLOW_XSTAT,
BNXT_DEVARG_MAX_NUM_KFLOWS,
+ BNXT_DEVARG_REP_BASED_PF,
+ BNXT_DEVARG_REP_IS_PF,
+ BNXT_DEVARG_REP_Q_R2F,
+ BNXT_DEVARG_REP_Q_F2R,
+ BNXT_DEVARG_REP_FC_R2F,
+ BNXT_DEVARG_REP_FC_F2R,
NULL
};
*/
#define BNXT_DEVARG_FLOW_XSTAT_INVALID(flow_xstat) ((flow_xstat) > 1)
+/*
+ * rep_is_pf == false to indicate VF representor
+ * rep_is_pf == true to indicate PF representor
+ */
+#define BNXT_DEVARG_REP_IS_PF_INVALID(rep_is_pf) ((rep_is_pf) > 1)
+
+/*
+ * rep_based_pf == Physical index of the PF
+ */
+#define BNXT_DEVARG_REP_BASED_PF_INVALID(rep_based_pf) ((rep_based_pf) > 15)
+/*
+ * rep_q_r2f == Logical COS Queue index for the rep to endpoint direction
+ */
+#define BNXT_DEVARG_REP_Q_R2F_INVALID(rep_q_r2f) ((rep_q_r2f) > 3)
+
+/*
+ * rep_q_f2r == Logical COS Queue index for the endpoint to rep direction
+ */
+#define BNXT_DEVARG_REP_Q_F2R_INVALID(rep_q_f2r) ((rep_q_f2r) > 3)
+
+/*
+ * rep_fc_r2f == Flow control for the representor to endpoint direction
+ */
+#define BNXT_DEVARG_REP_FC_R2F_INVALID(rep_fc_r2f) ((rep_fc_r2f) > 1)
+
+/*
+ * rep_fc_f2r == Flow control for the endpoint to representor direction
+ */
+#define BNXT_DEVARG_REP_FC_F2R_INVALID(rep_fc_f2r) ((rep_fc_f2r) > 1)
+
/*
* max_num_kflows must be >= 32
* and must be a power-of-2 supported value
speed_capa |= ETH_LINK_SPEED_50G;
if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB)
speed_capa |= ETH_LINK_SPEED_100G;
- if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_200GB)
+ if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G)
+ speed_capa |= ETH_LINK_SPEED_50G;
+ if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G)
+ speed_capa |= ETH_LINK_SPEED_100G;
+ if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_200G)
speed_capa |= ETH_LINK_SPEED_200G;
if (bp->link_info->auto_mode ==
dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT;
if (bp->flags & BNXT_FLAG_PTP_SUPPORTED)
dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP;
- dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT;
+ dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+ dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT |
+ dev_info->tx_queue_offload_capa;
dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
dev_info->speed_capa = bnxt_get_speed_capabilities(bp);
.wthresh = 0,
},
.rx_free_thresh = 32,
- /* If no descriptors available, pkts are dropped by default */
- .rx_drop_en = 1,
+ .rx_drop_en = BNXT_DEFAULT_RX_DROP_EN,
};
dev_info->default_txconf = (struct rte_eth_txconf) {
{
#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
#ifndef RTE_LIBRTE_IEEE1588
+ uint64_t offloads = eth_dev->data->dev_conf.txmode.offloads;
struct bnxt *bp = eth_dev->data->dev_private;
/*
* or tx offloads.
*/
if (!eth_dev->data->scattered_rx &&
- !eth_dev->data->dev_conf.txmode.offloads &&
+ !(offloads & ~DEV_TX_OFFLOAD_MBUF_FAST_FREE) &&
!BNXT_TRUFLOW_EN(bp)) {
PMD_DRV_LOG(INFO, "Using vector mode transmit for port %d\n",
eth_dev->data->port_id);
"Port %d scatter: %d tx offload: %" PRIX64 "\n",
eth_dev->data->port_id,
eth_dev->data->scattered_rx,
- eth_dev->data->dev_conf.txmode.offloads);
+ offloads);
#endif
#endif
return bnxt_xmit_pkts;
eth_dev->data->scattered_rx = bnxt_scattered_rx(eth_dev);
eth_dev->data->dev_started = 1;
- bnxt_link_update(eth_dev, 1, ETH_LINK_UP);
+ bnxt_link_update_op(eth_dev, 1);
if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
vlan_mask |= ETH_VLAN_FILTER_MASK;
struct bnxt *bp = eth_dev->data->dev_private;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+ struct rte_eth_link link;
eth_dev->data->dev_started = 0;
eth_dev->data->scattered_rx = 0;
rte_intr_disable(intr_handle);
/* Stop the child representors for this device */
- bnxt_vf_rep_stop_all(bp);
+ bnxt_rep_stop_all(bp);
/* delete the bnxt ULP port details */
bnxt_ulp_port_deinit(bp);
bnxt_cancel_fw_health_check(bp);
- bnxt_dev_set_link_down_op(eth_dev);
-
- /* Wait for link to be reset and the async notification to process.
- * During reset recovery, there is no need to wait and
- * VF/NPAR functions do not have privilege to change PHY config.
- */
- if (!is_bnxt_in_error(bp) && BNXT_SINGLE_PF(bp))
- bnxt_link_update(eth_dev, 1, ETH_LINK_DOWN);
+ /* Do not bring link down during reset recovery */
+ if (!is_bnxt_in_error(bp)) {
+ bnxt_dev_set_link_down_op(eth_dev);
+ /* Wait for link to be reset */
+ if (BNXT_SINGLE_PF(bp))
+ rte_delay_ms(500);
+ /* clear the recorded link status */
+ memset(&link, 0, sizeof(link));
+ rte_eth_linkstatus_set(eth_dev, &link);
+ }
/* Clean queue intr-vector mapping */
rte_intr_efd_disable(intr_handle);
bp->flow_stat->flow_count = 0;
}
-static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = eth_dev->data->dev_private;
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
/* cancel the recovery handler before remove dev */
rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp);
rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp);
rte_free(bp->grp_info);
bp->grp_info = NULL;
+
+ return 0;
}
static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev,
return rc;
}
-int bnxt_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete,
- bool exp_link_status)
+int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
{
int rc = 0;
struct bnxt *bp = eth_dev->data->dev_private;
struct rte_eth_link new;
- int cnt = exp_link_status ? BNXT_LINK_UP_WAIT_CNT :
- BNXT_LINK_DOWN_WAIT_CNT;
+ int cnt = wait_to_complete ? BNXT_MAX_LINK_WAIT_CNT :
+ BNXT_MIN_LINK_WAIT_CNT;
rc = is_bnxt_in_error(bp);
if (rc)
goto out;
}
- if (!wait_to_complete || new.link_status == exp_link_status)
+ if (!wait_to_complete || new.link_status)
break;
rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
} while (cnt--);
+ /* Only single function PF can bring phy down.
+ * When port is stopped, report link down for VF/MH/NPAR functions.
+ */
+ if (!BNXT_SINGLE_PF(bp) && !eth_dev->data->dev_started)
+ memset(&new, 0, sizeof(new));
+
out:
/* Timed out or success */
if (new.link_status != eth_dev->data->dev_link.link_status ||
return rc;
}
-int bnxt_link_update_op(struct rte_eth_dev *eth_dev,
- int wait_to_complete)
-{
- return bnxt_link_update(eth_dev, wait_to_complete, ETH_LINK_UP);
-}
-
static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = eth_dev->data->dev_private;
/* Update the default RSS VNIC(s) */
vnic = BNXT_GET_DEFAULT_VNIC(bp);
vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf);
+ vnic->hash_mode =
+ bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf,
+ ETH_RSS_LEVEL(rss_conf->rss_hf));
/*
* If hashkey is not specified, use the previously configured
hash_types &=
~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
}
+
+ rss_conf->rss_hf |=
+ bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode);
+
if (hash_types) {
PMD_DRV_LOG(ERR,
"Unknown RSS config from firmware (%08x), RSS disabled",
qinfo->nb_desc = rxq->nb_rx_desc;
qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
- qinfo->conf.rx_drop_en = 0;
+ qinfo->conf.rx_drop_en = rxq->drop_en;
qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
+ qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
}
static void
qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
qinfo->conf.tx_rs_thresh = 0;
qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
+ qinfo->conf.offloads = txq->offloads;
}
static const struct {
return -EIO;
if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {
- struct bnxt_vf_representor *vfr = dev->data->dev_private;
+ struct bnxt_representor *vfr = dev->data->dev_private;
bp = vfr->parent_dev->data->dev_private;
/* parent is deleted while children are still valid */
if (!bp) {
static void bnxt_dev_cleanup(struct bnxt *bp)
{
- bnxt_set_hwrm_link_config(bp, false);
+ bp->eth_dev->data->dev_link.link_status = 0;
bp->link_info->link_up = 0;
if (bp->eth_dev->data->dev_started)
bnxt_dev_stop_op(bp->eth_dev);
if (!BNXT_PF(bp))
return;
-#define ALLOW_FUNC(x) \
- { \
- uint32_t arg = (x); \
- bp->pf->vf_req_fwd[((arg) >> 5)] &= \
- ~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \
- }
-
- /* Forward all requests if firmware is new enough */
- if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&
- (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||
- ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {
- memset(bp->pf->vf_req_fwd, 0xff, sizeof(bp->pf->vf_req_fwd));
- } else {
- PMD_DRV_LOG(WARNING,
- "Firmware too old for VF mailbox functionality\n");
- memset(bp->pf->vf_req_fwd, 0, sizeof(bp->pf->vf_req_fwd));
- }
+ memset(bp->pf->vf_req_fwd, 0, sizeof(bp->pf->vf_req_fwd));
- /*
- * The following are used for driver cleanup. If we disallow these,
- * VF drivers can't clean up cleanly.
- */
- ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);
- ALLOW_FUNC(HWRM_VNIC_FREE);
- ALLOW_FUNC(HWRM_RING_FREE);
- ALLOW_FUNC(HWRM_RING_GRP_FREE);
- ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);
- ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);
- ALLOW_FUNC(HWRM_STAT_CTX_FREE);
- ALLOW_FUNC(HWRM_PORT_PHY_QCFG);
- ALLOW_FUNC(HWRM_VNIC_TPA_CFG);
+ if (!(bp->fw_cap & BNXT_FW_CAP_LINK_ADMIN))
+ BNXT_HWRM_CMD_TO_FORWARD(HWRM_PORT_PHY_QCFG);
+ BNXT_HWRM_CMD_TO_FORWARD(HWRM_FUNC_CFG);
+ BNXT_HWRM_CMD_TO_FORWARD(HWRM_FUNC_VF_CFG);
+ BNXT_HWRM_CMD_TO_FORWARD(HWRM_CFA_L2_FILTER_ALLOC);
+ BNXT_HWRM_CMD_TO_FORWARD(HWRM_OEM_CMD);
}
uint16_t
eth_dev = &rte_eth_devices[port_id];
if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
- struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ struct bnxt_representor *vfr = eth_dev->data->dev_private;
if (!vfr)
return 0;
eth_dev = &rte_eth_devices[port];
if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
- struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ struct bnxt_representor *vfr = eth_dev->data->dev_private;
if (!vfr)
return 0;
eth_dev = &rte_eth_devices[port];
if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
- struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ struct bnxt_representor *vfr = eth_dev->data->dev_private;
if (!vfr)
return 0;
uint16_t
bnxt_get_phy_port_id(uint16_t port_id)
{
- struct bnxt_vf_representor *vfr;
+ struct bnxt_representor *vfr;
struct rte_eth_dev *eth_dev;
struct bnxt *bp;
eth_dev = &rte_eth_devices[port_id];
if (BNXT_ETH_DEV_IS_REPRESENTOR(eth_dev)) {
- struct bnxt_vf_representor *vfr = eth_dev->data->dev_private;
+ struct bnxt_representor *vfr = eth_dev->data->dev_private;
if (!vfr)
return 0;
return -EINVAL;
}
- bp->flags |= BNXT_FLAG_TRUFLOW_EN;
- if (BNXT_TRUFLOW_EN(bp))
+ if (truflow) {
+ bp->flags |= BNXT_FLAG_TRUFLOW_EN;
PMD_DRV_LOG(INFO, "Host-based truflow feature enabled.\n");
+ } else {
+ bp->flags &= ~BNXT_FLAG_TRUFLOW_EN;
+ PMD_DRV_LOG(INFO, "Host-based truflow feature disabled.\n");
+ }
return 0;
}
return 0;
}
+static int
+bnxt_parse_devarg_rep_is_pf(__rte_unused const char *key,
+ const char *value, void *opaque_arg)
+{
+ struct bnxt_representor *vfr_bp = opaque_arg;
+ unsigned long rep_is_pf;
+ char *end = NULL;
+
+ if (!value || !opaque_arg) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_is_pf devargs.\n");
+ return -EINVAL;
+ }
+
+ rep_is_pf = strtoul(value, &end, 10);
+ if (end == NULL || *end != '\0' ||
+ (rep_is_pf == ULONG_MAX && errno == ERANGE)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_is_pf devargs.\n");
+ return -EINVAL;
+ }
+
+ if (BNXT_DEVARG_REP_IS_PF_INVALID(rep_is_pf)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid value passed to rep_is_pf devargs.\n");
+ return -EINVAL;
+ }
+
+ vfr_bp->flags |= rep_is_pf;
+ if (BNXT_REP_PF(vfr_bp))
+ PMD_DRV_LOG(INFO, "PF representor\n");
+ else
+ PMD_DRV_LOG(INFO, "VF representor\n");
+
+ return 0;
+}
+
+static int
+bnxt_parse_devarg_rep_based_pf(__rte_unused const char *key,
+ const char *value, void *opaque_arg)
+{
+ struct bnxt_representor *vfr_bp = opaque_arg;
+ unsigned long rep_based_pf;
+ char *end = NULL;
+
+ if (!value || !opaque_arg) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_based_pf "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ rep_based_pf = strtoul(value, &end, 10);
+ if (end == NULL || *end != '\0' ||
+ (rep_based_pf == ULONG_MAX && errno == ERANGE)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_based_pf "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ if (BNXT_DEVARG_REP_BASED_PF_INVALID(rep_based_pf)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid value passed to rep_based_pf devargs.\n");
+ return -EINVAL;
+ }
+
+ vfr_bp->rep_based_pf = rep_based_pf;
+ PMD_DRV_LOG(INFO, "rep-based-pf = %d\n", vfr_bp->rep_based_pf);
+
+ return 0;
+}
+
+static int
+bnxt_parse_devarg_rep_q_r2f(__rte_unused const char *key,
+ const char *value, void *opaque_arg)
+{
+ struct bnxt_representor *vfr_bp = opaque_arg;
+ unsigned long rep_q_r2f;
+ char *end = NULL;
+
+ if (!value || !opaque_arg) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_q_r2f "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ rep_q_r2f = strtoul(value, &end, 10);
+ if (end == NULL || *end != '\0' ||
+ (rep_q_r2f == ULONG_MAX && errno == ERANGE)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_q_r2f "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ if (BNXT_DEVARG_REP_Q_R2F_INVALID(rep_q_r2f)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid value passed to rep_q_r2f devargs.\n");
+ return -EINVAL;
+ }
+
+ vfr_bp->rep_q_r2f = rep_q_r2f;
+ vfr_bp->flags |= BNXT_REP_Q_R2F_VALID;
+ PMD_DRV_LOG(INFO, "rep-q-r2f = %d\n", vfr_bp->rep_q_r2f);
+
+ return 0;
+}
+
+static int
+bnxt_parse_devarg_rep_q_f2r(__rte_unused const char *key,
+ const char *value, void *opaque_arg)
+{
+ struct bnxt_representor *vfr_bp = opaque_arg;
+ unsigned long rep_q_f2r;
+ char *end = NULL;
+
+ if (!value || !opaque_arg) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_q_f2r "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ rep_q_f2r = strtoul(value, &end, 10);
+ if (end == NULL || *end != '\0' ||
+ (rep_q_f2r == ULONG_MAX && errno == ERANGE)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_q_f2r "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ if (BNXT_DEVARG_REP_Q_F2R_INVALID(rep_q_f2r)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid value passed to rep_q_f2r devargs.\n");
+ return -EINVAL;
+ }
+
+ vfr_bp->rep_q_f2r = rep_q_f2r;
+ vfr_bp->flags |= BNXT_REP_Q_F2R_VALID;
+ PMD_DRV_LOG(INFO, "rep-q-f2r = %d\n", vfr_bp->rep_q_f2r);
+
+ return 0;
+}
+
+static int
+bnxt_parse_devarg_rep_fc_r2f(__rte_unused const char *key,
+ const char *value, void *opaque_arg)
+{
+ struct bnxt_representor *vfr_bp = opaque_arg;
+ unsigned long rep_fc_r2f;
+ char *end = NULL;
+
+ if (!value || !opaque_arg) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_fc_r2f "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ rep_fc_r2f = strtoul(value, &end, 10);
+ if (end == NULL || *end != '\0' ||
+ (rep_fc_r2f == ULONG_MAX && errno == ERANGE)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_fc_r2f "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ if (BNXT_DEVARG_REP_FC_R2F_INVALID(rep_fc_r2f)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid value passed to rep_fc_r2f devargs.\n");
+ return -EINVAL;
+ }
+
+ vfr_bp->flags |= BNXT_REP_FC_R2F_VALID;
+ vfr_bp->rep_fc_r2f = rep_fc_r2f;
+ PMD_DRV_LOG(INFO, "rep-fc-r2f = %lu\n", rep_fc_r2f);
+
+ return 0;
+}
+
+static int
+bnxt_parse_devarg_rep_fc_f2r(__rte_unused const char *key,
+ const char *value, void *opaque_arg)
+{
+ struct bnxt_representor *vfr_bp = opaque_arg;
+ unsigned long rep_fc_f2r;
+ char *end = NULL;
+
+ if (!value || !opaque_arg) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_fc_f2r "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ rep_fc_f2r = strtoul(value, &end, 10);
+ if (end == NULL || *end != '\0' ||
+ (rep_fc_f2r == ULONG_MAX && errno == ERANGE)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid parameter passed to rep_fc_f2r "
+ "devargs.\n");
+ return -EINVAL;
+ }
+
+ if (BNXT_DEVARG_REP_FC_F2R_INVALID(rep_fc_f2r)) {
+ PMD_DRV_LOG(ERR,
+ "Invalid value passed to rep_fc_f2r devargs.\n");
+ return -EINVAL;
+ }
+
+ vfr_bp->flags |= BNXT_REP_FC_F2R_VALID;
+ vfr_bp->rep_fc_f2r = rep_fc_f2r;
+ PMD_DRV_LOG(INFO, "rep-fc-f2r = %lu\n", rep_fc_f2r);
+
+ return 0;
+}
+
static void
bnxt_parse_dev_args(struct bnxt *bp, struct rte_devargs *devargs)
{
bnxt_alloc_switch_domain(bp);
- /* Pass the information to the rte_eth_dev_close() that it should also
- * release the private port resources.
- */
- eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
-
PMD_DRV_LOG(INFO,
DRV_MODULE_NAME "found at mem %" PRIX64 ", node addr %pM\n",
pci_dev->mem_resource[0].phys_addr,
bnxt_free_int(bp);
bnxt_free_mem(bp, reconfig_dev);
+
bnxt_hwrm_func_buf_unrgtr(bp);
+ rte_free(bp->pf->vf_req_buf);
+
rc = bnxt_hwrm_func_driver_unregister(bp, 0);
bp->flags &= ~BNXT_FLAG_REGISTERED;
bnxt_free_ctx_mem(bp);
continue;
PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR pci remove\n",
vf_rep_eth_dev->data->port_id);
- rte_eth_dev_destroy(vf_rep_eth_dev, bnxt_vf_representor_uninit);
+ rte_eth_dev_destroy(vf_rep_eth_dev, bnxt_representor_uninit);
}
PMD_DRV_LOG(DEBUG, "BNXT Port:%d pci remove\n",
eth_dev->data->port_id);
static int bnxt_rep_port_probe(struct rte_pci_device *pci_dev,
struct rte_eth_devargs eth_da,
- struct rte_eth_dev *backing_eth_dev)
+ struct rte_eth_dev *backing_eth_dev,
+ const char *dev_args)
{
struct rte_eth_dev *vf_rep_eth_dev;
char name[RTE_ETH_NAME_MAX_LEN];
struct bnxt *backing_bp;
uint16_t num_rep;
int i, ret = 0;
+ struct rte_kvargs *kvlist;
num_rep = eth_da.nb_representor_ports;
if (num_rep > BNXT_MAX_VF_REPS) {
return 0;
for (i = 0; i < num_rep; i++) {
- struct bnxt_vf_representor representor = {
+ struct bnxt_representor representor = {
.vf_id = eth_da.representor_ports[i],
.switch_domain_id = backing_bp->switch_domain_id,
.parent_dev = backing_eth_dev
snprintf(name, sizeof(name), "net_%s_representor_%d",
pci_dev->device.name, eth_da.representor_ports[i]);
+ kvlist = rte_kvargs_parse(dev_args, bnxt_dev_args);
+ if (kvlist) {
+ /*
+ * Handler for "rep_is_pf" devarg.
+ * Invoked as for ex: "-w 000:00:0d.0,
+ * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
+ */
+ rte_kvargs_process(kvlist, BNXT_DEVARG_REP_IS_PF,
+ bnxt_parse_devarg_rep_is_pf,
+ (void *)&representor);
+ /*
+ * Handler for "rep_based_pf" devarg.
+ * Invoked as for ex: "-w 000:00:0d.0,
+ * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
+ */
+ rte_kvargs_process(kvlist, BNXT_DEVARG_REP_BASED_PF,
+ bnxt_parse_devarg_rep_based_pf,
+ (void *)&representor);
+ /*
+ * Handler for "rep_based_pf" devarg.
+ * Invoked as for ex: "-w 000:00:0d.0,
+ * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
+ */
+ rte_kvargs_process(kvlist, BNXT_DEVARG_REP_Q_R2F,
+ bnxt_parse_devarg_rep_q_r2f,
+ (void *)&representor);
+ /*
+ * Handler for "rep_based_pf" devarg.
+ * Invoked as for ex: "-w 000:00:0d.0,
+ * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
+ */
+ rte_kvargs_process(kvlist, BNXT_DEVARG_REP_Q_F2R,
+ bnxt_parse_devarg_rep_q_f2r,
+ (void *)&representor);
+ /*
+ * Handler for "rep_based_pf" devarg.
+ * Invoked as for ex: "-w 000:00:0d.0,
+ * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
+ */
+ rte_kvargs_process(kvlist, BNXT_DEVARG_REP_FC_R2F,
+ bnxt_parse_devarg_rep_fc_r2f,
+ (void *)&representor);
+ /*
+ * Handler for "rep_based_pf" devarg.
+ * Invoked as for ex: "-w 000:00:0d.0,
+ * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
+ */
+ rte_kvargs_process(kvlist, BNXT_DEVARG_REP_FC_F2R,
+ bnxt_parse_devarg_rep_fc_f2r,
+ (void *)&representor);
+ }
+
ret = rte_eth_dev_create(&pci_dev->device, name,
- sizeof(struct bnxt_vf_representor),
+ sizeof(struct bnxt_representor),
NULL, NULL,
- bnxt_vf_representor_init,
+ bnxt_representor_init,
&representor);
if (ret) {
PMD_DRV_LOG(ERR, "failed to create bnxt vf "
}
PMD_DRV_LOG(DEBUG, "BNXT Port:%d VFR pci probe\n",
- backing_eth_dev->data->port_id);
+ backing_eth_dev->data->port_id);
backing_bp->rep_info[representor.vf_id].vfr_eth_dev =
vf_rep_eth_dev;
backing_bp->num_reps++;
+
}
return 0;
}
PMD_DRV_LOG(DEBUG, "BNXT Port:%d pci probe\n",
backing_eth_dev->data->port_id);
+
+ if (!num_rep)
+ return ret;
+
/* probe representor ports now */
- ret = bnxt_rep_port_probe(pci_dev, eth_da, backing_eth_dev);
+ ret = bnxt_rep_port_probe(pci_dev, eth_da, backing_eth_dev,
+ pci_dev->device.devargs->args);
return ret;
}
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
if (eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
return rte_eth_dev_destroy(eth_dev,
- bnxt_vf_representor_uninit);
+ bnxt_representor_uninit);
else
return rte_eth_dev_destroy(eth_dev,
bnxt_dev_uninit);