return err;
}
+ /*clear fdir filter flag in function table*/
+ hinic_free_fdir_filter(nic_dev);
+
return HINIC_OK;
}
return rc;
}
+/**
+ * DPDK callback to bring the link UP.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ *
+ * @return
+ * 0 on success, negative errno value on failure.
+ */
+static int hinic_dev_set_link_up(struct rte_eth_dev *dev)
+{
+ struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ int ret;
+
+ ret = hinic_set_xsfp_tx_status(nic_dev->hwdev, true);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Enable port tx xsfp failed, dev_name: %s, port_id: %d",
+ nic_dev->proc_dev_name, dev->data->port_id);
+ return ret;
+ }
+
+ /* link status follow phy port status, up will open pma */
+ ret = hinic_set_port_enable(nic_dev->hwdev, true);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Set mac link up failed, dev_name: %s, port_id: %d",
+ nic_dev->proc_dev_name, dev->data->port_id);
+
+ return ret;
+}
+
+/**
+ * DPDK callback to bring the link DOWN.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ *
+ * @return
+ * 0 on success, negative errno value on failure.
+ */
+static int hinic_dev_set_link_down(struct rte_eth_dev *dev)
+{
+ struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ int ret;
+
+ ret = hinic_set_xsfp_tx_status(nic_dev->hwdev, false);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Disable port tx xsfp failed, dev_name: %s, port_id: %d",
+ nic_dev->proc_dev_name, dev->data->port_id);
+ return ret;
+ }
+
+ /* link status follow phy port status, up will close pma */
+ ret = hinic_set_port_enable(nic_dev->hwdev, false);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Set mac link down failed, dev_name: %s, port_id: %d",
+ nic_dev->proc_dev_name, dev->data->port_id);
+
+ return ret;
+}
+
/**
* DPDK callback to start the device.
*
/* clean root context */
hinic_free_qp_ctxts(nic_dev->hwdev);
+ hinic_free_fdir_filter(nic_dev);
+
/* free mbuf */
hinic_free_all_rx_mbuf(dev);
hinic_free_all_tx_mbuf(dev);
return 0;
}
+/**
+ * DPDK callback to manage filter operations
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param filter_type
+ * Filter type.
+ * @param filter_op
+ * Operation to perform.
+ * @param arg
+ * Pointer to operation-specific structure.
+ *
+ * @return
+ * 0 on success, negative errno value on failure.
+ */
+static int hinic_dev_filter_ctrl(struct rte_eth_dev *dev,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op,
+ void *arg)
+{
+ struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+ int func_id = hinic_global_func_id(nic_dev->hwdev);
+
+ switch (filter_type) {
+ case RTE_ETH_FILTER_GENERIC:
+ if (filter_op != RTE_ETH_FILTER_GET)
+ return -EINVAL;
+ *(const void **)arg = &hinic_flow_ops;
+ break;
+ default:
+ PMD_DRV_LOG(INFO, "Filter type (%d) not supported",
+ filter_type);
+ return -EINVAL;
+ }
+
+ PMD_DRV_LOG(INFO, "Set filter_ctrl succeed, func_id: 0x%x, filter_type: 0x%x,"
+ "filter_op: 0x%x.", func_id, filter_type, filter_op);
+ return 0;
+}
+
static int hinic_set_default_pause_feature(struct hinic_nic_dev *nic_dev)
{
struct nic_pause_config pause_config = {0};
.rx_queue_setup = hinic_rx_queue_setup,
.tx_queue_setup = hinic_tx_queue_setup,
.dev_start = hinic_dev_start,
+ .dev_set_link_up = hinic_dev_set_link_up,
+ .dev_set_link_down = hinic_dev_set_link_down,
.link_update = hinic_link_update,
.rx_queue_release = hinic_rx_queue_release,
.tx_queue_release = hinic_tx_queue_release,
.mac_addr_remove = hinic_mac_addr_remove,
.mac_addr_add = hinic_mac_addr_add,
.set_mc_addr_list = hinic_set_mc_addr_list,
+ .filter_ctrl = hinic_dev_filter_ctrl,
};
static const struct eth_dev_ops hinic_pmd_vf_ops = {
.mac_addr_remove = hinic_mac_addr_remove,
.mac_addr_add = hinic_mac_addr_add,
.set_mc_addr_list = hinic_set_mc_addr_list,
+ .filter_ctrl = hinic_dev_filter_ctrl,
};
static int hinic_func_init(struct rte_eth_dev *eth_dev)
struct rte_pci_device *pci_dev;
struct rte_ether_addr *eth_addr;
struct hinic_nic_dev *nic_dev;
+ struct hinic_filter_info *filter_info;
u32 mac_size;
int rc;
}
hinic_set_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
+ /* initialize filter info */
+ filter_info = &nic_dev->filter;
+ memset(filter_info, 0, sizeof(struct hinic_filter_info));
+ /* initialize 5tuple filter list */
+ TAILQ_INIT(&filter_info->fivetuple_list);
+ TAILQ_INIT(&nic_dev->filter_ntuple_list);
+ TAILQ_INIT(&nic_dev->filter_ethertype_list);
+ TAILQ_INIT(&nic_dev->filter_fdir_rule_list);
+ TAILQ_INIT(&nic_dev->hinic_flow_list);
+
hinic_set_bit(HINIC_DEV_INIT, &nic_dev->dev_status);
PMD_DRV_LOG(INFO, "Initialize %s in primary successfully",
eth_dev->data->name);