{
struct hns3_adapter *hns = dev->data->dev_private;
struct hns3_hw *hw = &hns->hw;
+ bool pvid_en_state_change;
+ uint16_t pvid_state;
int ret;
if (pvid > RTE_ETHER_MAX_VLAN_ID) {
return -EINVAL;
}
+ /*
+ * If PVID configuration state change, should refresh the PVID
+ * configuration state in struct hns3_tx_queue/hns3_rx_queue.
+ */
+ pvid_state = hw->port_base_vlan_cfg.state;
+ if ((on && pvid_state == HNS3_PORT_BASE_VLAN_ENABLE) ||
+ (!on && pvid_state == HNS3_PORT_BASE_VLAN_DISABLE))
+ pvid_en_state_change = false;
+ else
+ pvid_en_state_change = true;
+
rte_spinlock_lock(&hw->lock);
ret = hns3_vlan_pvid_configure(hns, pvid, on);
rte_spinlock_unlock(&hw->lock);
- return ret;
+ if (ret)
+ return ret;
+
+ if (pvid_en_state_change)
+ hns3_update_all_queues_pvid_state(hw);
+
+ return 0;
}
static void
info->max_rx_queues = queue_num;
info->max_tx_queues = hw->tqps_num;
info->max_rx_pktlen = HNS3_MAX_FRAME_LEN; /* CRC included */
- info->min_rx_bufsize = hw->rx_buf_len;
+ info->min_rx_bufsize = HNS3_MIN_BD_BUF_SIZE;
info->max_mac_addrs = HNS3_UC_MACADDR_NUM;
info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD;
info->max_lro_pkt_size = HNS3_MAX_LRO_SIZE;
DEV_TX_OFFLOAD_TCP_CKSUM |
DEV_TX_OFFLOAD_UDP_CKSUM |
DEV_TX_OFFLOAD_SCTP_CKSUM |
- DEV_TX_OFFLOAD_VLAN_INSERT |
- DEV_TX_OFFLOAD_QINQ_INSERT |
DEV_TX_OFFLOAD_MULTI_SEGS |
DEV_TX_OFFLOAD_TCP_TSO |
DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
DEV_TX_OFFLOAD_GRE_TNL_TSO |
DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
- info->tx_queue_offload_capa);
+ info->tx_queue_offload_capa |
+ hns3_txvlan_cap_get(hw));
info->rx_desc_lim = (struct rte_eth_desc_lim) {
.nb_max = HNS3_MAX_RING_DESC,
.nb_max = HNS3_MAX_RING_DESC,
.nb_min = HNS3_MIN_RING_DESC,
.nb_align = HNS3_ALIGN_RING_DESC,
+ .nb_seg_max = HNS3_MAX_TSO_BD_PER_PKT,
+ .nb_mtu_seg_max = HNS3_MAX_NON_TSO_BD_PER_PKT,
};
info->vmdq_queue_num = 0;
return 0;
}
+static int
+hns3_get_capability(struct hns3_hw *hw)
+{
+ struct rte_pci_device *pci_dev;
+ struct rte_eth_dev *eth_dev;
+ uint16_t device_id;
+ uint8_t revision;
+ int ret;
+
+ eth_dev = &rte_eth_devices[hw->data->port_id];
+ pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ device_id = pci_dev->id.device_id;
+
+ if (device_id == HNS3_DEV_ID_25GE_RDMA ||
+ device_id == HNS3_DEV_ID_50GE_RDMA ||
+ device_id == HNS3_DEV_ID_100G_RDMA_MACSEC)
+ hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_DCB_B, 1);
+
+ /* 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: %d", ret);
+ return -EIO;
+ }
+ hw->revision = revision;
+
+ return 0;
+}
+
static int
hns3_get_board_configuration(struct hns3_hw *hw)
{
hw->mac.media_type = cfg.media_type;
hw->rss_size_max = cfg.rss_size_max;
hw->rss_dis_flag = false;
- hw->rx_buf_len = cfg.rx_buf_len;
memcpy(hw->mac.mac_addr, cfg.mac_addr, RTE_ETHER_ADDR_LEN);
hw->mac.phy_addr = cfg.phy_addr;
hw->mac.default_addr_setted = false;
return ret;
}
+ /* Get device capability */
+ ret = hns3_get_capability(hw);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "failed to get device capability: %d.", ret);
+ return ret;
+ }
+
/* Get pf resource */
ret = hns3_query_pf_resource(hw);
if (ret) {
return ret;
}
+static int
+hns3_clear_hw(struct hns3_hw *hw)
+{
+ struct hns3_cmd_desc desc;
+ int ret;
+
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CLEAR_HW_STATE, false);
+
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret && ret != -EOPNOTSUPP)
+ return ret;
+
+ return 0;
+}
+
static int
hns3_init_pf(struct rte_eth_dev *eth_dev)
{
goto err_cmd_init;
}
+ /*
+ * To ensure that the hardware environment is clean during
+ * initialization, the driver actively clear the hardware environment
+ * during initialization, including PF and corresponding VFs' vlan, mac,
+ * flow table configurations, etc.
+ */
+ ret = hns3_clear_hw(hw);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "failed to clear hardware: %d", ret);
+ goto err_cmd_init;
+ }
+
ret = rte_intr_callback_register(&pci_dev->intr_handle,
hns3_interrupt_handler,
eth_dev);
static int
hns3_dev_init(struct rte_eth_dev *eth_dev)
{
- struct rte_device *dev = eth_dev->device;
- struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev);
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),
hns3_set_rxtx_function(eth_dev);
eth_dev->dev_ops = &hns3_eth_dev_ops;
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
- hns3_mp_init_secondary();
+ ret = hns3_mp_init_secondary();
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Failed to init for secondary "
+ "process, ret = %d", ret);
+ goto err_mp_init_secondary;
+ }
+
hw->secondary_cnt++;
return 0;
}
- hns3_mp_init_primary();
- hw->adapter_state = HNS3_NIC_UNINITIALIZED;
-
- if (device_id == HNS3_DEV_ID_25GE_RDMA ||
- device_id == HNS3_DEV_ID_50GE_RDMA ||
- device_id == HNS3_DEV_ID_100G_RDMA_MACSEC)
- hns3_set_bit(hw->flag, HNS3_DEV_SUPPORT_DCB_B, 1);
+ ret = hns3_mp_init_primary();
+ if (ret) {
+ PMD_INIT_LOG(ERR,
+ "Failed to init for primary process, ret = %d",
+ ret);
+ goto err_mp_init_primary;
+ }
+ hw->adapter_state = HNS3_NIC_UNINITIALIZED;
hns->is_vf = false;
hw->data = eth_dev->data;
err_init_pf:
rte_free(hw->reset.wait_data);
+
err_init_reset:
+ hns3_mp_uninit_primary();
+
+err_mp_init_primary:
+err_mp_init_secondary:
eth_dev->dev_ops = NULL;
eth_dev->rx_pkt_burst = NULL;
eth_dev->tx_pkt_burst = NULL;