#include <unistd.h>
-#include <unistd.h>
-
#include <rte_byteorder.h>
#include <rte_common.h>
#include <rte_cycles.h>
uint32_t *data = msg;
uint8_t *bar;
uint8_t *valid;
+ uint16_t max_req_len = bp->max_req_len;
+ struct hwrm_short_input short_input = { 0 };
+
+ if (bp->flags & BNXT_FLAG_SHORT_CMD) {
+ void *short_cmd_req = bp->hwrm_short_cmd_req_addr;
+
+ memset(short_cmd_req, 0, bp->max_req_len);
+ memcpy(short_cmd_req, req, msg_len);
+
+ short_input.req_type = rte_cpu_to_le_16(req->req_type);
+ short_input.signature = rte_cpu_to_le_16(
+ HWRM_SHORT_REQ_SIGNATURE_SHORT_CMD);
+ short_input.size = rte_cpu_to_le_16(msg_len);
+ short_input.req_addr =
+ rte_cpu_to_le_64(bp->hwrm_short_cmd_req_dma_addr);
+
+ data = (uint32_t *)&short_input;
+ msg_len = sizeof(short_input);
+
+ /* Sync memory write before updating doorbell */
+ rte_wmb();
+
+ max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
+ }
/* Write request msg to hwrm channel */
for (i = 0; i < msg_len; i += 4) {
}
/* Zero the rest of the request space */
- for (; i < bp->max_req_len; i += 4) {
+ for (; i < max_req_len; i += 4) {
bar = (uint8_t *)bp->bar0 + i;
rte_write32(0, bar);
}
req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
}
- if (vlan_count && vlan_table) {
- mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
+ if (vlan_table) {
+ if (!(mask & HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN))
+ mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
rte_mem_virt2phy(vlan_table));
req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
return rc;
}
+int bnxt_hwrm_cfa_vlan_antispoof_cfg(struct bnxt *bp, uint16_t fid,
+ uint16_t vlan_count,
+ struct bnxt_vlan_antispoof_table_entry *vlan_table)
+{
+ int rc = 0;
+ struct hwrm_cfa_vlan_antispoof_cfg_input req = {.req_type = 0 };
+ struct hwrm_cfa_vlan_antispoof_cfg_output *resp =
+ bp->hwrm_cmd_resp_addr;
+
+ /*
+ * Older HWRM versions did not support this command, and the set_rx_mask
+ * list was used for anti-spoof. In 1.8.0, the TX path configuration was
+ * removed from set_rx_mask call, and this command was added.
+ *
+ * This command is also present from 1.7.8.11 and higher,
+ * as well as 1.7.8.0
+ */
+ if (bp->fw_ver < ((1 << 24) | (8 << 16))) {
+ if (bp->fw_ver != ((1 << 24) | (7 << 16) | (8 << 8))) {
+ if (bp->fw_ver < ((1 << 24) | (7 << 16) | (8 << 8) |
+ (11)))
+ return 0;
+ }
+ }
+ HWRM_PREP(req, CFA_VLAN_ANTISPOOF_CFG, -1, resp);
+ req.fid = rte_cpu_to_le_16(fid);
+
+ req.vlan_tag_mask_tbl_addr =
+ rte_cpu_to_le_64(rte_mem_virt2phy(vlan_table));
+ req.num_vlan_entries = rte_cpu_to_le_32((uint32_t)vlan_count);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
int bnxt_hwrm_clear_filter(struct bnxt *bp,
struct bnxt_filter_info *filter)
{
struct hwrm_cfa_l2_filter_free_input req = {.req_type = 0 };
struct hwrm_cfa_l2_filter_free_output *resp = bp->hwrm_cmd_resp_addr;
+ if (filter->fw_l2_filter_id == UINT64_MAX)
+ return 0;
+
HWRM_PREP(req, CFA_L2_FILTER_FREE, -1, resp);
req.l2_filter_id = rte_cpu_to_le_64(filter->fw_l2_filter_id);
struct hwrm_cfa_l2_filter_alloc_output *resp = bp->hwrm_cmd_resp_addr;
uint32_t enables = 0;
+ if (filter->fw_l2_filter_id != UINT64_MAX)
+ bnxt_hwrm_clear_filter(bp, filter);
+
HWRM_PREP(req, CFA_L2_FILTER_ALLOC, -1, resp);
req.flags = rte_cpu_to_le_32(filter->flags);
else
rte_mem_lock_page(
bp->pf.vf_info[i].vlan_table);
+ bp->pf.vf_info[i].vlan_as_table =
+ rte_zmalloc("VF VLAN AS table",
+ getpagesize(),
+ getpagesize());
+ if (bp->pf.vf_info[i].vlan_as_table == NULL)
+ RTE_LOG(ERR, PMD,
+ "Alloc VLAN AS table for VF %d fail\n",
+ i);
+ else
+ rte_mem_lock_page(
+ bp->pf.vf_info[i].vlan_as_table);
STAILQ_INIT(&bp->pf.vf_info[i].filter);
}
}
uint32_t fw_version;
uint16_t max_resp_len;
char type[RTE_MEMZONE_NAMESIZE];
+ uint32_t dev_caps_cfg;
+ bp->max_req_len = HWRM_MAX_REQ_LEN;
HWRM_PREP(req, VER_GET, -1, resp);
req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
RTE_LOG(ERR, PMD, "Unsupported request length\n");
rc = -EINVAL;
}
- bp->max_req_len = resp->max_req_win_len;
+ bp->max_req_len = rte_le_to_cpu_16(resp->max_req_win_len);
max_resp_len = resp->max_resp_len;
+ dev_caps_cfg = rte_le_to_cpu_32(resp->dev_caps_cfg);
+
if (bp->max_resp_len != max_resp_len) {
sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x",
bp->pdev->addr.domain, bp->pdev->addr.bus,
bp->max_resp_len = max_resp_len;
}
+ 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_INPUTUIRED)) {
+ RTE_LOG(DEBUG, PMD, "Short command supported\n");
+
+ rte_free(bp->hwrm_short_cmd_req_addr);
+
+ bp->hwrm_short_cmd_req_addr = rte_malloc(type,
+ bp->max_req_len, 0);
+ if (bp->hwrm_short_cmd_req_addr == NULL) {
+ rc = -ENOMEM;
+ goto error;
+ }
+ rte_mem_lock_page(bp->hwrm_short_cmd_req_addr);
+ bp->hwrm_short_cmd_req_dma_addr =
+ rte_mem_virt2phy(bp->hwrm_short_cmd_req_addr);
+ if (bp->hwrm_short_cmd_req_dma_addr == 0) {
+ rte_free(bp->hwrm_short_cmd_req_addr);
+ RTE_LOG(ERR, PMD,
+ "Unable to map buffer to physical memory.\n");
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ bp->flags |= BNXT_FLAG_SHORT_CMD;
+ }
+
error:
rte_spinlock_unlock(&bp->hwrm_lock);
return rc;
struct hwrm_port_phy_cfg_input req = {0};
struct hwrm_port_phy_cfg_output *resp = bp->hwrm_cmd_resp_addr;
uint32_t enables = 0;
+ uint32_t link_speed_mask =
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK;
HWRM_PREP(req, PORT_PHY_CFG, -1, resp);
* any auto mode, even "none".
*/
if (!conf->link_speed) {
- req.auto_mode |= conf->auto_mode;
- enables = HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
- req.auto_link_speed_mask = conf->auto_link_speed_mask;
- enables |=
- HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK;
- req.auto_link_speed = bp->link_info.auto_link_speed;
- enables |=
+ req.auto_mode = conf->auto_mode;
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
+ if (conf->auto_mode ==
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK) {
+ req.auto_link_speed_mask =
+ conf->auto_link_speed_mask;
+ enables |= link_speed_mask;
+ }
+ if (bp->link_info.auto_link_speed) {
+ req.auto_link_speed =
+ bp->link_info.auto_link_speed;
+ enables |=
HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED;
+ }
}
req.auto_duplex = conf->duplex;
enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX;
HWRM_CHECK_RESULT;
link_info->phy_link_status = resp->link;
- if (link_info->phy_link_status != HWRM_PORT_PHY_QCFG_OUTPUT_LINK_NO_LINK) {
- link_info->link_up = 1;
- link_info->link_speed = rte_le_to_cpu_16(resp->link_speed);
- } else {
- link_info->link_up = 0;
- link_info->link_speed = 0;
- }
+ link_info->link_up =
+ (link_info->phy_link_status ==
+ HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK) ? 1 : 0;
+ link_info->link_speed = rte_le_to_cpu_16(resp->link_speed);
link_info->duplex = resp->duplex;
link_info->pause = resp->pause;
link_info->auto_pause = resp->auto_pause;
ETHER_CRC_LEN + VLAN_TAG_SIZE;
HWRM_PREP(req, VNIC_ALLOC, -1, resp);
+ if (vnic->func_default)
+ req.flags = HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT;
rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
HWRM_CHECK_RESULT;
vnic->fw_vnic_id = rte_le_to_cpu_16(resp->vnic_id);
+ RTE_LOG(DEBUG, PMD, "VNIC ID %x\n", vnic->fw_vnic_id);
return rc;
}
uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
struct bnxt_plcmodes_cfg pmodes;
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+ RTE_LOG(DEBUG, PMD, "VNIC ID %x\n", vnic->fw_vnic_id);
+ return rc;
+ }
+
rc = bnxt_hwrm_vnic_plcmodes_qcfg(bp, vnic, &pmodes);
if (rc)
return rc;
struct hwrm_vnic_qcfg_input req = {.req_type = 0 };
struct hwrm_vnic_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+ RTE_LOG(DEBUG, PMD, "VNIC QCFG ID %d\n", vnic->fw_vnic_id);
+ return rc;
+ }
HWRM_PREP(req, VNIC_QCFG, -1, resp);
req.enables =
HWRM_CHECK_RESULT;
vnic->rss_rule = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+ RTE_LOG(DEBUG, PMD, "VNIC RSS Rule %x\n", vnic->rss_rule);
return rc;
}
struct hwrm_vnic_rss_cos_lb_ctx_free_output *resp =
bp->hwrm_cmd_resp_addr;
+ if (vnic->rss_rule == 0xffff) {
+ RTE_LOG(DEBUG, PMD, "VNIC RSS Rule %x\n", vnic->rss_rule);
+ return rc;
+ }
HWRM_PREP(req, VNIC_RSS_COS_LB_CTX_FREE, -1, resp);
req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->rss_rule);
struct hwrm_vnic_free_input req = {.req_type = 0 };
struct hwrm_vnic_free_output *resp = bp->hwrm_cmd_resp_addr;
- if (vnic->fw_vnic_id == INVALID_HW_RING_ID)
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+ RTE_LOG(DEBUG, PMD, "VNIC FREE ID %x\n", vnic->fw_vnic_id);
return rc;
+ }
HWRM_PREP(req, VNIC_FREE, -1, resp);
{
/* Release memzone */
rte_free(bp->hwrm_cmd_resp_addr);
+ rte_free(bp->hwrm_short_cmd_req_addr);
bp->hwrm_cmd_resp_addr = NULL;
+ bp->hwrm_short_cmd_req_addr = NULL;
bp->hwrm_cmd_resp_dma_addr = 0;
+ bp->hwrm_short_cmd_req_dma_addr = 0;
}
int bnxt_alloc_hwrm_resources(struct bnxt *bp)
sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", pdev->addr.domain,
pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
- bp->max_req_len = HWRM_MAX_REQ_LEN;
bp->max_resp_len = HWRM_MAX_RESP_LEN;
bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
return 0;
}
-static uint16_t bnxt_parse_eth_link_speed_mask(uint32_t link_speed)
+static uint16_t
+bnxt_parse_eth_link_speed_mask(struct bnxt *bp, uint32_t link_speed)
{
uint16_t ret = 0;
- if (link_speed == ETH_LINK_SPEED_AUTONEG)
+ if (link_speed == ETH_LINK_SPEED_AUTONEG) {
+ if (bp->link_info.support_speeds)
+ return bp->link_info.support_speeds;
link_speed = BNXT_SUPPORTED_SPEEDS;
+ }
if (link_speed & ETH_LINK_SPEED_100M)
ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB;
"Get link config failed with rc %d\n", rc);
goto exit;
}
- if (link_info->link_up)
+ if (link_info->link_speed)
link->link_speed =
bnxt_parse_hw_link_speed(link_info->link_speed);
else
- link->link_speed = ETH_LINK_SPEED_10M;
+ link->link_speed = ETH_SPEED_NUM_NONE;
link->link_duplex = bnxt_parse_hw_link_duplex(link_info->duplex);
link->link_status = link_info->link_up;
link->link_autoneg = link_info->auto_mode ==
HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE ?
- ETH_LINK_SPEED_FIXED : ETH_LINK_SPEED_AUTONEG;
+ ETH_LINK_FIXED : ETH_LINK_AUTONEG;
exit:
return rc;
}
link_req.auto_mode =
HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK;
link_req.auto_link_speed_mask =
- bnxt_parse_eth_link_speed_mask(dev_conf->link_speeds);
+ bnxt_parse_eth_link_speed_mask(bp,
+ dev_conf->link_speeds);
} else {
link_req.phy_flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE;
link_req.link_speed = speed;
"Set link config failed with rc %d\n", rc);
}
- rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
error:
return rc;
}
HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
- req.mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
- ETHER_CRC_LEN + VLAN_TAG_SIZE);
+ req.mtu = rte_cpu_to_le_16(BNXT_MAX_MTU);
req.mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
ETHER_CRC_LEN + VLAN_TAG_SIZE);
req.num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx);
reserve_resources_from_vf(bp, &req, i);
bp->pf.active_vfs++;
+ bnxt_hwrm_func_clr_stats(bp, bp->pf.vf_info[i].fid);
}
/*
return rc;
}
-int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf,
+ uint32_t flags)
{
struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
struct hwrm_func_cfg_input req = {0};
HWRM_PREP(req, FUNC_CFG, -1, resp);
req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
- req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+ req.flags = rte_cpu_to_le_32(flags);
rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
HWRM_CHECK_RESULT;
return rc;
}
-static void bnxt_vnic_count(struct bnxt_vnic_info *vnic, void *cbdata)
+static void
+bnxt_vnic_count(struct bnxt_vnic_info *vnic __rte_unused, void *cbdata)
{
uint32_t *count = cbdata;
- if (vnic->func_default)
- *count = *count + 1;
+ *count = *count + 1;
}
static int bnxt_vnic_count_hwrm_stub(struct bnxt *bp __rte_unused,
return 0;
}
-int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf)
+int bnxt_vf_vnic_count(struct bnxt *bp, uint16_t vf)
{
uint32_t count = 0;
rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf);
if (rc)
break;
- if (vnic.mru == 4) /* Indicates unallocated */
+ if (vnic.mru <= 4) /* Indicates unallocated */
continue;
vnic_cb(&vnic, cbdata);