rxmode = &dev->data->dev_conf.rxmode;
tmp_mask = (unsigned int)mask;
if (tmp_mask & ETH_VLAN_FILTER_MASK) {
- /* Enable or disable VLAN filter */
- enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ?
- true : false;
+ /* ignore vlan filter configuration during promiscuous mode */
+ if (!dev->data->promiscuous) {
+ /* Enable or disable VLAN filter */
+ enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ?
+ true : false;
- ret = hns3_enable_vlan_filter(hns, enable);
- if (ret) {
- rte_spinlock_unlock(&hw->lock);
- hns3_err(hw, "failed to %s rx filter, ret = %d",
- enable ? "enable" : "disable", ret);
- return ret;
+ ret = hns3_enable_vlan_filter(hns, enable);
+ if (ret) {
+ rte_spinlock_unlock(&hw->lock);
+ hns3_err(hw, "failed to %s rx filter, ret = %d",
+ enable ? "enable" : "disable", ret);
+ return ret;
+ }
}
}
bool enable;
int ret;
- /* restore vlan filter states */
- offloads = hw->data->dev_conf.rxmode.offloads;
- enable = offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? true : false;
- ret = hns3_enable_vlan_filter(hns, enable);
- if (ret) {
- hns3_err(hw, "failed to restore vlan rx filter conf, ret = %d",
- ret);
- return ret;
+ if (!hw->data->promiscuous) {
+ /* restore vlan filter states */
+ offloads = hw->data->dev_conf.rxmode.offloads;
+ enable = offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? true : false;
+ ret = hns3_enable_vlan_filter(hns, enable);
+ if (ret) {
+ hns3_err(hw, "failed to restore vlan rx filter conf, "
+ "ret = %d", ret);
+ return ret;
+ }
}
ret = hns3_set_vlan_rx_offload_cfg(hns, &pf->vtag_config.rx_vcfg);
return ret;
}
+ /*
+ * If pvid config is not set in rte_eth_conf, driver needn't to set
+ * VLAN pvid related configuration to hardware.
+ */
+ if (txmode->pvid == 0 && txmode->hw_vlan_insert_pvid == 0)
+ return 0;
+
/* Apply pvid setting */
ret = hns3_vlan_pvid_set(dev, txmode->pvid,
txmode->hw_vlan_insert_pvid);
err = ret;
rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
addr);
- hns3_dbg(hw, "%s mc mac addr: %s failed",
- del ? "Remove" : "Restore", mac_str);
+ hns3_dbg(hw, "%s mc mac addr: %s failed for pf: ret = %d",
+ del ? "Remove" : "Restore", mac_str, ret);
}
}
return err;
* Rx interrupt.
*/
vec = hw->num_msi - 1; /* vector 0 for misc interrupt, not for queue */
- hw->intr_tqps_num = vec - 1; /* the last interrupt is reserved */
+ /* vec - 1: the last interrupt is reserved */
+ hw->intr_tqps_num = vec > hw->tqps_num ? hw->tqps_num : vec - 1;
for (i = 0; i < hw->intr_tqps_num; i++) {
/*
* Set gap limiter and rate limiter configuration of queue's
{
struct hns3_adapter *hns = eth_dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
+ uint32_t version = hw->fw_version;
int ret;
- ret = snprintf(fw_version, fw_size, "0x%08x", hw->fw_version);
+ ret = snprintf(fw_version, fw_size, "%lu.%lu.%lu.%lu",
+ hns3_get_field(version, HNS3_FW_VERSION_BYTE3_M,
+ HNS3_FW_VERSION_BYTE3_S),
+ hns3_get_field(version, HNS3_FW_VERSION_BYTE2_M,
+ HNS3_FW_VERSION_BYTE2_S),
+ hns3_get_field(version, HNS3_FW_VERSION_BYTE1_M,
+ HNS3_FW_VERSION_BYTE1_S),
+ hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M,
+ HNS3_FW_VERSION_BYTE0_S));
ret += 1; /* add the size of '\0' */
if (fw_size < (uint32_t)ret)
return ret;
struct hns3_pf *pf = &hns->pf;
struct hns3_pf_res_cmd *req;
struct hns3_cmd_desc desc;
- uint16_t num_msi;
int ret;
hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_PF_RSRC, true);
pf->dv_buf_size = roundup(pf->dv_buf_size, HNS3_BUF_SIZE_UNIT);
- num_msi = hns3_get_field(rte_le_to_cpu_16(req->pf_intr_vector_number),
- HNS3_VEC_NUM_M, HNS3_VEC_NUM_S);
- hw->num_msi = (num_msi > hw->tqps_num + 1) ? hw->tqps_num + 1 : num_msi;
+ hw->num_msi =
+ hns3_get_field(rte_le_to_cpu_16(req->pf_intr_vector_number),
+ HNS3_VEC_NUM_M, HNS3_VEC_NUM_S);
return 0;
}
static int
hns3_dev_promiscuous_enable(struct rte_eth_dev *dev)
{
+ bool allmulti = dev->data->all_multicast ? true : false;
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
+ uint64_t offloads;
+ int err;
int ret;
rte_spinlock_lock(&hw->lock);
ret = hns3_set_promisc_mode(hw, true, true);
- rte_spinlock_unlock(&hw->lock);
- if (ret)
- hns3_err(hw, "Failed to enable promiscuous mode, ret = %d",
+ if (ret) {
+ rte_spinlock_unlock(&hw->lock);
+ hns3_err(hw, "failed to enable promiscuous mode, ret = %d",
ret);
+ return ret;
+ }
+
+ /*
+ * When promiscuous mode was enabled, disable the vlan filter to let
+ * all packets coming in in the receiving direction.
+ */
+ offloads = dev->data->dev_conf.rxmode.offloads;
+ if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
+ ret = hns3_enable_vlan_filter(hns, false);
+ if (ret) {
+ hns3_err(hw, "failed to enable promiscuous mode due to "
+ "failure to disable vlan filter, ret = %d",
+ ret);
+ err = hns3_set_promisc_mode(hw, false, allmulti);
+ if (err)
+ hns3_err(hw, "failed to restore promiscuous "
+ "status after disable vlan filter "
+ "failed during enabling promiscuous "
+ "mode, ret = %d", ret);
+ }
+ }
+
+ rte_spinlock_unlock(&hw->lock);
return ret;
}
bool allmulti = dev->data->all_multicast ? true : false;
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
+ uint64_t offloads;
+ int err;
int ret;
/* If now in all_multicast mode, must remain in all_multicast mode. */
rte_spinlock_lock(&hw->lock);
ret = hns3_set_promisc_mode(hw, false, allmulti);
- rte_spinlock_unlock(&hw->lock);
- if (ret)
- hns3_err(hw, "Failed to disable promiscuous mode, ret = %d",
+ if (ret) {
+ rte_spinlock_unlock(&hw->lock);
+ hns3_err(hw, "failed to disable promiscuous mode, ret = %d",
ret);
+ return ret;
+ }
+ /* when promiscuous mode was disabled, restore the vlan filter status */
+ offloads = dev->data->dev_conf.rxmode.offloads;
+ if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
+ ret = hns3_enable_vlan_filter(hns, true);
+ if (ret) {
+ hns3_err(hw, "failed to disable promiscuous mode due to"
+ " failure to restore vlan filter, ret = %d",
+ ret);
+ err = hns3_set_promisc_mode(hw, true, true);
+ if (err)
+ hns3_err(hw, "failed to restore promiscuous "
+ "status after enabling vlan filter "
+ "failed during disabling promiscuous "
+ "mode, ret = %d", ret);
+ }
+ }
+ rte_spinlock_unlock(&hw->lock);
return ret;
}
ret = hns3_set_promisc_mode(hw, false, true);
rte_spinlock_unlock(&hw->lock);
if (ret)
- hns3_err(hw, "Failed to enable allmulticast mode, ret = %d",
+ hns3_err(hw, "failed to enable allmulticast mode, ret = %d",
ret);
return ret;
ret = hns3_set_promisc_mode(hw, false, false);
rte_spinlock_unlock(&hw->lock);
if (ret)
- hns3_err(hw, "Failed to disable allmulticast mode, ret = %d",
+ hns3_err(hw, "failed to disable allmulticast mode, ret = %d",
ret);
return ret;
{
struct hns3_hw *hw = &hns->hw;
bool allmulti = hw->data->all_multicast ? true : false;
+ int ret;
- if (hw->data->promiscuous)
- return hns3_set_promisc_mode(hw, true, true);
+ if (hw->data->promiscuous) {
+ ret = hns3_set_promisc_mode(hw, true, true);
+ if (ret)
+ hns3_err(hw, "failed to restore promiscuous mode, "
+ "ret = %d", ret);
+ return ret;
+ }
- return hns3_set_promisc_mode(hw, false, allmulti);
+ ret = hns3_set_promisc_mode(hw, false, allmulti);
+ if (ret)
+ hns3_err(hw, "failed to restore allmulticast mode, ret = %d",
+ ret);
+ return ret;
}
static int
struct hns3_adapter *hns = eth_dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
uint16_t device_id = pci_dev->id.device_id;
+ uint8_t revision;
int ret;
PMD_INIT_FUNC_TRACE();
+
+ /* Get PCI revision id */
+ ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN,
+ HNS3_PCI_REVISION_ID);
+ if (ret != HNS3_PCI_REVISION_ID_LEN) {
+ PMD_INIT_LOG(ERR, "Failed to read pci revision id, ret = %d",
+ ret);
+ return -EIO;
+ }
+ hw->revision = revision;
+
eth_dev->process_private = (struct hns3_process_private *)
rte_zmalloc_socket("hns3_filter_list",
sizeof(struct hns3_process_private),