+ struct ice_dcf_adapter *ad = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &ad->real_hw;
+ struct ice_tx_queue *txq;
+ int err;
+
+ if (tx_queue_id >= dev->data->nb_tx_queues)
+ return -EINVAL;
+
+ err = ice_dcf_switch_queue(hw, tx_queue_id, false, false);
+ if (err) {
+ PMD_DRV_LOG(ERR, "Failed to switch TX queue %u off",
+ tx_queue_id);
+ return err;
+ }
+
+ txq = dev->data->tx_queues[tx_queue_id];
+ txq->tx_rel_mbufs(txq);
+ reset_tx_queue(txq);
+ dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+ return 0;
+}
+
+static int
+ice_dcf_start_queues(struct rte_eth_dev *dev)
+{
+ struct ice_rx_queue *rxq;
+ struct ice_tx_queue *txq;
+ int nb_rxq = 0;
+ int nb_txq, i;
+
+ for (nb_txq = 0; nb_txq < dev->data->nb_tx_queues; nb_txq++) {
+ txq = dev->data->tx_queues[nb_txq];
+ if (txq->tx_deferred_start)
+ continue;
+ if (ice_dcf_tx_queue_start(dev, nb_txq) != 0) {
+ PMD_DRV_LOG(ERR, "Fail to start queue %u", nb_txq);
+ goto tx_err;
+ }
+ }
+
+ for (nb_rxq = 0; nb_rxq < dev->data->nb_rx_queues; nb_rxq++) {
+ rxq = dev->data->rx_queues[nb_rxq];
+ if (rxq->rx_deferred_start)
+ continue;
+ if (ice_dcf_rx_queue_start(dev, nb_rxq) != 0) {
+ PMD_DRV_LOG(ERR, "Fail to start queue %u", nb_rxq);
+ goto rx_err;
+ }
+ }
+
+ return 0;
+
+ /* stop the started queues if failed to start all queues */
+rx_err:
+ for (i = 0; i < nb_rxq; i++)
+ ice_dcf_rx_queue_stop(dev, i);
+tx_err:
+ for (i = 0; i < nb_txq; i++)
+ ice_dcf_tx_queue_stop(dev, i);
+
+ return -1;
+}
+
+static int
+ice_dcf_dev_start(struct rte_eth_dev *dev)
+{
+ struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
+ struct rte_intr_handle *intr_handle = dev->intr_handle;
+ struct ice_adapter *ad = &dcf_ad->parent;
+ struct ice_dcf_hw *hw = &dcf_ad->real_hw;
+ int ret;
+
+ ad->pf.adapter_stopped = 0;
+
+ hw->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
+ dev->data->nb_tx_queues);
+
+ ret = ice_dcf_init_rx_queues(dev);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Fail to init queues");
+ return ret;
+ }
+
+ if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+ ret = ice_dcf_init_rss(hw);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Failed to configure RSS");
+ return ret;
+ }
+ }
+
+ ret = ice_dcf_configure_queues(hw);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Fail to config queues");
+ return ret;
+ }
+
+ ret = ice_dcf_config_rx_queues_irqs(dev, intr_handle);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Fail to config rx queues' irqs");
+ return ret;
+ }
+
+ if (dev->data->dev_conf.intr_conf.rxq != 0) {
+ rte_intr_disable(intr_handle);
+ rte_intr_enable(intr_handle);
+ }
+
+ ret = ice_dcf_start_queues(dev);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Failed to enable queues");
+ return ret;
+ }
+
+ ret = ice_dcf_add_del_all_mac_addr(hw, true);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "Failed to add mac addr");
+ return ret;
+ }
+
+ dev->data->dev_link.link_status = ETH_LINK_UP;
+
+ return 0;
+}
+
+static void
+ice_dcf_stop_queues(struct rte_eth_dev *dev)
+{
+ struct ice_dcf_adapter *ad = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &ad->real_hw;
+ struct ice_rx_queue *rxq;
+ struct ice_tx_queue *txq;
+ int ret, i;
+
+ /* Stop All queues */
+ ret = ice_dcf_disable_queues(hw);
+ if (ret)
+ PMD_DRV_LOG(WARNING, "Fail to stop queues");
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq)
+ continue;
+ txq->tx_rel_mbufs(txq);
+ reset_tx_queue(txq);
+ dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+ }
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+ if (!rxq)
+ continue;
+ rxq->rx_rel_mbufs(rxq);
+ reset_rx_queue(rxq);
+ dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+ }
+}
+
+static void
+ice_dcf_dev_stop(struct rte_eth_dev *dev)
+{
+ struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
+ struct rte_intr_handle *intr_handle = dev->intr_handle;
+ struct ice_adapter *ad = &dcf_ad->parent;
+
+ if (ad->pf.adapter_stopped == 1) {
+ PMD_DRV_LOG(DEBUG, "Port is already stopped");
+ return;
+ }
+
+ ice_dcf_stop_queues(dev);
+
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+
+ ice_dcf_add_del_all_mac_addr(&dcf_ad->real_hw, false);
+ dev->data->dev_link.link_status = ETH_LINK_DOWN;
+ ad->pf.adapter_stopped = 1;
+}
+
+static int
+ice_dcf_dev_configure(struct rte_eth_dev *dev)
+{
+ struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
+ struct ice_adapter *ad = &dcf_ad->parent;
+
+ ad->rx_bulk_alloc_allowed = true;
+ ad->tx_simple_allowed = true;
+
+ if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
+ dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;
+
+ return 0;
+}
+
+static int
+ice_dcf_dev_info_get(struct rte_eth_dev *dev,
+ struct rte_eth_dev_info *dev_info)
+{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+
+ dev_info->max_mac_addrs = 1;
+ dev_info->max_rx_queues = hw->vsi_res->num_queue_pairs;
+ dev_info->max_tx_queues = hw->vsi_res->num_queue_pairs;
+ dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN;
+ dev_info->max_rx_pktlen = ICE_FRAME_SIZE_MAX;
+ dev_info->hash_key_size = hw->vf_res->rss_key_size;
+ dev_info->reta_size = hw->vf_res->rss_lut_size;
+ dev_info->flow_type_rss_offloads = ICE_RSS_OFFLOAD_ALL;
+
+ dev_info->rx_offload_capa =
+ DEV_RX_OFFLOAD_VLAN_STRIP |
+ DEV_RX_OFFLOAD_IPV4_CKSUM |
+ DEV_RX_OFFLOAD_UDP_CKSUM |
+ DEV_RX_OFFLOAD_TCP_CKSUM |
+ DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
+ DEV_RX_OFFLOAD_SCATTER |
+ DEV_RX_OFFLOAD_JUMBO_FRAME |
+ DEV_RX_OFFLOAD_VLAN_FILTER |
+ DEV_RX_OFFLOAD_RSS_HASH;
+ dev_info->tx_offload_capa =
+ DEV_TX_OFFLOAD_VLAN_INSERT |
+ DEV_TX_OFFLOAD_IPV4_CKSUM |
+ DEV_TX_OFFLOAD_UDP_CKSUM |
+ DEV_TX_OFFLOAD_TCP_CKSUM |
+ DEV_TX_OFFLOAD_SCTP_CKSUM |
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+ DEV_TX_OFFLOAD_TCP_TSO |
+ DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+ DEV_TX_OFFLOAD_GRE_TNL_TSO |
+ DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+ DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
+ DEV_TX_OFFLOAD_MULTI_SEGS;
+
+ dev_info->default_rxconf = (struct rte_eth_rxconf) {
+ .rx_thresh = {
+ .pthresh = ICE_DEFAULT_RX_PTHRESH,
+ .hthresh = ICE_DEFAULT_RX_HTHRESH,
+ .wthresh = ICE_DEFAULT_RX_WTHRESH,
+ },
+ .rx_free_thresh = ICE_DEFAULT_RX_FREE_THRESH,
+ .rx_drop_en = 0,
+ .offloads = 0,
+ };
+
+ dev_info->default_txconf = (struct rte_eth_txconf) {
+ .tx_thresh = {
+ .pthresh = ICE_DEFAULT_TX_PTHRESH,
+ .hthresh = ICE_DEFAULT_TX_HTHRESH,
+ .wthresh = ICE_DEFAULT_TX_WTHRESH,
+ },
+ .tx_free_thresh = ICE_DEFAULT_TX_FREE_THRESH,
+ .tx_rs_thresh = ICE_DEFAULT_TX_RSBIT_THRESH,
+ .offloads = 0,
+ };
+
+ dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+ .nb_max = ICE_MAX_RING_DESC,
+ .nb_min = ICE_MIN_RING_DESC,
+ .nb_align = ICE_ALIGN_RING_DESC,
+ };
+
+ dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+ .nb_max = ICE_MAX_RING_DESC,
+ .nb_min = ICE_MIN_RING_DESC,
+ .nb_align = ICE_ALIGN_RING_DESC,
+ };
+