1c1d14583SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2c1d14583SBruce Richardson * Copyright(c) 2020 Intel Corporation 3c1d14583SBruce Richardson */ 4c1d14583SBruce Richardson 5c1d14583SBruce Richardson #include <errno.h> 6c1d14583SBruce Richardson #include <stdbool.h> 7c1d14583SBruce Richardson #include <sys/queue.h> 8c1d14583SBruce Richardson #include <sys/types.h> 9c1d14583SBruce Richardson #include <unistd.h> 10c1d14583SBruce Richardson 11c1d14583SBruce Richardson #include <rte_interrupts.h> 12c1d14583SBruce Richardson #include <rte_debug.h> 13c1d14583SBruce Richardson #include <rte_pci.h> 14c1d14583SBruce Richardson #include <rte_eal.h> 15c1d14583SBruce Richardson #include <rte_ether.h> 16c1d14583SBruce Richardson #include <ethdev_pci.h> 17c1d14583SBruce Richardson #include <rte_kvargs.h> 18c1d14583SBruce Richardson #include <rte_malloc.h> 19c1d14583SBruce Richardson #include <rte_memzone.h> 20c1d14583SBruce Richardson #include <dev_driver.h> 21c1d14583SBruce Richardson 22c1d14583SBruce Richardson #include <iavf_devids.h> 23c1d14583SBruce Richardson 24c1d14583SBruce Richardson #include "ice_generic_flow.h" 25c1d14583SBruce Richardson #include "ice_dcf_ethdev.h" 26c1d14583SBruce Richardson #include "ice_rxtx.h" 27552979dfSBruce Richardson #include "../common/tx.h" 28c1d14583SBruce Richardson 29c1d14583SBruce Richardson #define DCF_NUM_MACADDR_MAX 64 30c1d14583SBruce Richardson 31c1d14583SBruce Richardson static int dcf_add_del_mc_addr_list(struct ice_dcf_hw *hw, 32c1d14583SBruce Richardson struct rte_ether_addr *mc_addrs, 33c1d14583SBruce Richardson uint32_t mc_addrs_num, bool add); 34c1d14583SBruce Richardson 35c1d14583SBruce Richardson static int 36c1d14583SBruce Richardson ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, 37c1d14583SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel); 38c1d14583SBruce Richardson static int 39c1d14583SBruce Richardson ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, 40c1d14583SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel); 41c1d14583SBruce Richardson 42c1d14583SBruce Richardson static int 43c1d14583SBruce Richardson ice_dcf_dev_init(struct rte_eth_dev *eth_dev); 44c1d14583SBruce Richardson 45c1d14583SBruce Richardson static int 46c1d14583SBruce Richardson ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev); 47c1d14583SBruce Richardson 48c1d14583SBruce Richardson static int 49c1d14583SBruce Richardson ice_dcf_cap_check_handler(__rte_unused const char *key, 50c1d14583SBruce Richardson const char *value, __rte_unused void *opaque); 51c1d14583SBruce Richardson 52c1d14583SBruce Richardson static int 53c1d14583SBruce Richardson ice_dcf_engine_disabled_handler(__rte_unused const char *key, 54c1d14583SBruce Richardson const char *value, __rte_unused void *opaque); 55c1d14583SBruce Richardson 56c1d14583SBruce Richardson struct ice_devarg { 57c1d14583SBruce Richardson enum ice_dcf_devrarg type; 58c1d14583SBruce Richardson const char *key; 59c1d14583SBruce Richardson int (*handler)(__rte_unused const char *key, 60c1d14583SBruce Richardson const char *value, __rte_unused void *opaque); 61c1d14583SBruce Richardson }; 62c1d14583SBruce Richardson 63c1d14583SBruce Richardson static const struct ice_devarg ice_devargs_table[] = { 64c1d14583SBruce Richardson {ICE_DCF_DEVARG_CAP, "cap", ice_dcf_cap_check_handler}, 65c1d14583SBruce Richardson {ICE_DCF_DEVARG_ACL, "acl", ice_dcf_engine_disabled_handler}, 66c1d14583SBruce Richardson }; 67c1d14583SBruce Richardson 68c1d14583SBruce Richardson struct rte_ice_dcf_xstats_name_off { 69c1d14583SBruce Richardson char name[RTE_ETH_XSTATS_NAME_SIZE]; 70c1d14583SBruce Richardson unsigned int offset; 71c1d14583SBruce Richardson }; 72c1d14583SBruce Richardson 73c1d14583SBruce Richardson static const struct rte_ice_dcf_xstats_name_off rte_ice_dcf_stats_strings[] = { 74c1d14583SBruce Richardson {"rx_bytes", offsetof(struct ice_dcf_eth_stats, rx_bytes)}, 75c1d14583SBruce Richardson {"rx_unicast_packets", offsetof(struct ice_dcf_eth_stats, rx_unicast)}, 76c1d14583SBruce Richardson {"rx_multicast_packets", offsetof(struct ice_dcf_eth_stats, rx_multicast)}, 77c1d14583SBruce Richardson {"rx_broadcast_packets", offsetof(struct ice_dcf_eth_stats, rx_broadcast)}, 78c1d14583SBruce Richardson {"rx_dropped_packets", offsetof(struct ice_dcf_eth_stats, rx_discards)}, 79c1d14583SBruce Richardson {"rx_unknown_protocol_packets", offsetof(struct ice_dcf_eth_stats, 80c1d14583SBruce Richardson rx_unknown_protocol)}, 81c1d14583SBruce Richardson {"tx_bytes", offsetof(struct ice_dcf_eth_stats, tx_bytes)}, 82c1d14583SBruce Richardson {"tx_unicast_packets", offsetof(struct ice_dcf_eth_stats, tx_unicast)}, 83c1d14583SBruce Richardson {"tx_multicast_packets", offsetof(struct ice_dcf_eth_stats, tx_multicast)}, 84c1d14583SBruce Richardson {"tx_broadcast_packets", offsetof(struct ice_dcf_eth_stats, tx_broadcast)}, 85c1d14583SBruce Richardson {"tx_dropped_packets", offsetof(struct ice_dcf_eth_stats, tx_discards)}, 86c1d14583SBruce Richardson {"tx_error_packets", offsetof(struct ice_dcf_eth_stats, tx_errors)}, 87c1d14583SBruce Richardson }; 88c1d14583SBruce Richardson 89c1d14583SBruce Richardson #define ICE_DCF_NB_XSTATS (sizeof(rte_ice_dcf_stats_strings) / \ 90c1d14583SBruce Richardson sizeof(rte_ice_dcf_stats_strings[0])) 91c1d14583SBruce Richardson 92c1d14583SBruce Richardson static uint16_t 93c1d14583SBruce Richardson ice_dcf_recv_pkts(__rte_unused void *rx_queue, 94c1d14583SBruce Richardson __rte_unused struct rte_mbuf **bufs, 95c1d14583SBruce Richardson __rte_unused uint16_t nb_pkts) 96c1d14583SBruce Richardson { 97c1d14583SBruce Richardson return 0; 98c1d14583SBruce Richardson } 99c1d14583SBruce Richardson 100c1d14583SBruce Richardson static uint16_t 101c1d14583SBruce Richardson ice_dcf_xmit_pkts(__rte_unused void *tx_queue, 102c1d14583SBruce Richardson __rte_unused struct rte_mbuf **bufs, 103c1d14583SBruce Richardson __rte_unused uint16_t nb_pkts) 104c1d14583SBruce Richardson { 105c1d14583SBruce Richardson return 0; 106c1d14583SBruce Richardson } 107c1d14583SBruce Richardson 108c1d14583SBruce Richardson static int 109c1d14583SBruce Richardson ice_dcf_init_rxq(struct rte_eth_dev *dev, struct ice_rx_queue *rxq) 110c1d14583SBruce Richardson { 111c1d14583SBruce Richardson struct ice_dcf_adapter *dcf_ad = dev->data->dev_private; 112c1d14583SBruce Richardson struct rte_eth_dev_data *dev_data = dev->data; 113c1d14583SBruce Richardson struct iavf_hw *hw = &dcf_ad->real_hw.avf; 114c1d14583SBruce Richardson uint16_t buf_size, max_pkt_len; 115c1d14583SBruce Richardson 116c1d14583SBruce Richardson buf_size = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM; 117c1d14583SBruce Richardson rxq->rx_hdr_len = 0; 118c1d14583SBruce Richardson rxq->rx_buf_len = RTE_ALIGN_FLOOR(buf_size, (1 << ICE_RLAN_CTX_DBUF_S)); 119c1d14583SBruce Richardson rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, ICE_RX_MAX_DATA_BUF_SIZE); 120c1d14583SBruce Richardson max_pkt_len = RTE_MIN(ICE_SUPPORT_CHAIN_NUM * rxq->rx_buf_len, 121c1d14583SBruce Richardson dev->data->mtu + ICE_ETH_OVERHEAD); 122c1d14583SBruce Richardson 123c1d14583SBruce Richardson /* Check maximum packet length is set correctly. */ 124c1d14583SBruce Richardson if (max_pkt_len <= RTE_ETHER_MIN_LEN || 125c1d14583SBruce Richardson max_pkt_len > ICE_FRAME_SIZE_MAX) { 126c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "maximum packet length must be " 127c1d14583SBruce Richardson "larger than %u and smaller than %u", 128c1d14583SBruce Richardson (uint32_t)RTE_ETHER_MIN_LEN, 129c1d14583SBruce Richardson (uint32_t)ICE_FRAME_SIZE_MAX); 130c1d14583SBruce Richardson return -EINVAL; 131c1d14583SBruce Richardson } 132c1d14583SBruce Richardson 133c1d14583SBruce Richardson rxq->max_pkt_len = max_pkt_len; 134c1d14583SBruce Richardson if ((dev_data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER) || 135c1d14583SBruce Richardson (rxq->max_pkt_len + 2 * RTE_VLAN_HLEN) > buf_size) { 136c1d14583SBruce Richardson dev_data->scattered_rx = 1; 137c1d14583SBruce Richardson } 138c1d14583SBruce Richardson rxq->qrx_tail = hw->hw_addr + IAVF_QRX_TAIL1(rxq->queue_id); 139c1d14583SBruce Richardson IAVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1); 140c1d14583SBruce Richardson IAVF_WRITE_FLUSH(hw); 141c1d14583SBruce Richardson 142c1d14583SBruce Richardson return 0; 143c1d14583SBruce Richardson } 144c1d14583SBruce Richardson 145c1d14583SBruce Richardson static int 146c1d14583SBruce Richardson ice_dcf_init_rx_queues(struct rte_eth_dev *dev) 147c1d14583SBruce Richardson { 148c1d14583SBruce Richardson struct ice_rx_queue **rxq = 149c1d14583SBruce Richardson (struct ice_rx_queue **)dev->data->rx_queues; 150c1d14583SBruce Richardson int i, ret; 151c1d14583SBruce Richardson 152c1d14583SBruce Richardson for (i = 0; i < dev->data->nb_rx_queues; i++) { 153c1d14583SBruce Richardson if (!rxq[i] || !rxq[i]->q_set) 154c1d14583SBruce Richardson continue; 155c1d14583SBruce Richardson ret = ice_dcf_init_rxq(dev, rxq[i]); 156c1d14583SBruce Richardson if (ret) 157c1d14583SBruce Richardson return ret; 158c1d14583SBruce Richardson } 159c1d14583SBruce Richardson 160c1d14583SBruce Richardson ice_set_rx_function(dev); 161c1d14583SBruce Richardson ice_set_tx_function(dev); 162c1d14583SBruce Richardson 163c1d14583SBruce Richardson return 0; 164c1d14583SBruce Richardson } 165c1d14583SBruce Richardson 166c1d14583SBruce Richardson #define IAVF_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET 167c1d14583SBruce Richardson #define IAVF_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET 168c1d14583SBruce Richardson 169c1d14583SBruce Richardson #define IAVF_ITR_INDEX_DEFAULT 0 170c1d14583SBruce Richardson #define IAVF_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */ 171c1d14583SBruce Richardson #define IAVF_QUEUE_ITR_INTERVAL_MAX 8160 /* 8160 us */ 172c1d14583SBruce Richardson 173c1d14583SBruce Richardson static inline uint16_t 174c1d14583SBruce Richardson iavf_calc_itr_interval(int16_t interval) 175c1d14583SBruce Richardson { 176c1d14583SBruce Richardson if (interval < 0 || interval > IAVF_QUEUE_ITR_INTERVAL_MAX) 177c1d14583SBruce Richardson interval = IAVF_QUEUE_ITR_INTERVAL_DEFAULT; 178c1d14583SBruce Richardson 179c1d14583SBruce Richardson /* Convert to hardware count, as writing each 1 represents 2 us */ 180c1d14583SBruce Richardson return interval / 2; 181c1d14583SBruce Richardson } 182c1d14583SBruce Richardson 183c1d14583SBruce Richardson static int 184c1d14583SBruce Richardson ice_dcf_config_rx_queues_irqs(struct rte_eth_dev *dev, 185c1d14583SBruce Richardson struct rte_intr_handle *intr_handle) 186c1d14583SBruce Richardson { 187c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 188c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 189c1d14583SBruce Richardson uint16_t interval, i; 190c1d14583SBruce Richardson int vec; 191c1d14583SBruce Richardson 192c1d14583SBruce Richardson if (rte_intr_cap_multiple(intr_handle) && 193c1d14583SBruce Richardson dev->data->dev_conf.intr_conf.rxq) { 194c1d14583SBruce Richardson if (rte_intr_efd_enable(intr_handle, dev->data->nb_rx_queues)) 195c1d14583SBruce Richardson return -1; 196c1d14583SBruce Richardson } 197c1d14583SBruce Richardson 198c1d14583SBruce Richardson if (rte_intr_dp_is_en(intr_handle)) { 199c1d14583SBruce Richardson if (rte_intr_vec_list_alloc(intr_handle, "intr_vec", 200c1d14583SBruce Richardson dev->data->nb_rx_queues)) { 201c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to allocate %d rx intr_vec", 202c1d14583SBruce Richardson dev->data->nb_rx_queues); 203c1d14583SBruce Richardson return -1; 204c1d14583SBruce Richardson } 205c1d14583SBruce Richardson } 206c1d14583SBruce Richardson 207c1d14583SBruce Richardson if (!dev->data->dev_conf.intr_conf.rxq || 208c1d14583SBruce Richardson !rte_intr_dp_is_en(intr_handle)) { 209c1d14583SBruce Richardson /* Rx interrupt disabled, Map interrupt only for writeback */ 210c1d14583SBruce Richardson hw->nb_msix = 1; 211c1d14583SBruce Richardson if (hw->vf_res->vf_cap_flags & 212c1d14583SBruce Richardson VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) { 213c1d14583SBruce Richardson /* If WB_ON_ITR supports, enable it */ 214c1d14583SBruce Richardson hw->msix_base = IAVF_RX_VEC_START; 215c1d14583SBruce Richardson /* Set the ITR for index zero, to 2us to make sure that 216c1d14583SBruce Richardson * we leave time for aggregation to occur, but don't 217c1d14583SBruce Richardson * increase latency dramatically. 218c1d14583SBruce Richardson */ 219c1d14583SBruce Richardson IAVF_WRITE_REG(&hw->avf, 220c1d14583SBruce Richardson IAVF_VFINT_DYN_CTLN1(hw->msix_base - 1), 221c1d14583SBruce Richardson (0 << IAVF_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) | 222c1d14583SBruce Richardson IAVF_VFINT_DYN_CTLN1_WB_ON_ITR_MASK | 223c1d14583SBruce Richardson (2UL << IAVF_VFINT_DYN_CTLN1_INTERVAL_SHIFT)); 224c1d14583SBruce Richardson } else { 225c1d14583SBruce Richardson /* If no WB_ON_ITR offload flags, need to set 226c1d14583SBruce Richardson * interrupt for descriptor write back. 227c1d14583SBruce Richardson */ 228c1d14583SBruce Richardson hw->msix_base = IAVF_MISC_VEC_ID; 229c1d14583SBruce Richardson 230c1d14583SBruce Richardson /* set ITR to max */ 231c1d14583SBruce Richardson interval = 232c1d14583SBruce Richardson iavf_calc_itr_interval(IAVF_QUEUE_ITR_INTERVAL_MAX); 233c1d14583SBruce Richardson IAVF_WRITE_REG(&hw->avf, IAVF_VFINT_DYN_CTL01, 234c1d14583SBruce Richardson IAVF_VFINT_DYN_CTL01_INTENA_MASK | 235c1d14583SBruce Richardson (IAVF_ITR_INDEX_DEFAULT << 236c1d14583SBruce Richardson IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT) | 237c1d14583SBruce Richardson (interval << 238c1d14583SBruce Richardson IAVF_VFINT_DYN_CTL01_INTERVAL_SHIFT)); 239c1d14583SBruce Richardson } 240c1d14583SBruce Richardson IAVF_WRITE_FLUSH(&hw->avf); 241c1d14583SBruce Richardson /* map all queues to the same interrupt */ 242c1d14583SBruce Richardson for (i = 0; i < dev->data->nb_rx_queues; i++) 243c1d14583SBruce Richardson hw->rxq_map[hw->msix_base] |= 1 << i; 244c1d14583SBruce Richardson } else { 245c1d14583SBruce Richardson if (!rte_intr_allow_others(intr_handle)) { 246c1d14583SBruce Richardson hw->nb_msix = 1; 247c1d14583SBruce Richardson hw->msix_base = IAVF_MISC_VEC_ID; 248c1d14583SBruce Richardson for (i = 0; i < dev->data->nb_rx_queues; i++) { 249c1d14583SBruce Richardson hw->rxq_map[hw->msix_base] |= 1 << i; 250c1d14583SBruce Richardson rte_intr_vec_list_index_set(intr_handle, 251c1d14583SBruce Richardson i, IAVF_MISC_VEC_ID); 252c1d14583SBruce Richardson } 253c1d14583SBruce Richardson PMD_DRV_LOG(DEBUG, 254c1d14583SBruce Richardson "vector %u are mapping to all Rx queues", 255c1d14583SBruce Richardson hw->msix_base); 256c1d14583SBruce Richardson } else { 257c1d14583SBruce Richardson /* If Rx interrupt is required, and we can use 258c1d14583SBruce Richardson * multi interrupts, then the vec is from 1 259c1d14583SBruce Richardson */ 260c1d14583SBruce Richardson hw->nb_msix = RTE_MIN(hw->vf_res->max_vectors, 261c1d14583SBruce Richardson rte_intr_nb_efd_get(intr_handle)); 262c1d14583SBruce Richardson hw->msix_base = IAVF_MISC_VEC_ID; 263c1d14583SBruce Richardson vec = IAVF_MISC_VEC_ID; 264c1d14583SBruce Richardson for (i = 0; i < dev->data->nb_rx_queues; i++) { 265c1d14583SBruce Richardson hw->rxq_map[vec] |= 1 << i; 266c1d14583SBruce Richardson rte_intr_vec_list_index_set(intr_handle, 267c1d14583SBruce Richardson i, vec++); 268c1d14583SBruce Richardson if (vec >= hw->nb_msix) 269c1d14583SBruce Richardson vec = IAVF_RX_VEC_START; 270c1d14583SBruce Richardson } 271c1d14583SBruce Richardson PMD_DRV_LOG(DEBUG, 272c1d14583SBruce Richardson "%u vectors are mapping to %u Rx queues", 273c1d14583SBruce Richardson hw->nb_msix, dev->data->nb_rx_queues); 274c1d14583SBruce Richardson } 275c1d14583SBruce Richardson } 276c1d14583SBruce Richardson 277c1d14583SBruce Richardson if (ice_dcf_config_irq_map(hw)) { 278c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "config interrupt mapping failed"); 279c1d14583SBruce Richardson return -1; 280c1d14583SBruce Richardson } 281c1d14583SBruce Richardson return 0; 282c1d14583SBruce Richardson } 283c1d14583SBruce Richardson 284c1d14583SBruce Richardson static int 285c1d14583SBruce Richardson alloc_rxq_mbufs(struct ice_rx_queue *rxq) 286c1d14583SBruce Richardson { 287c1d14583SBruce Richardson volatile union ice_rx_flex_desc *rxd; 288c1d14583SBruce Richardson struct rte_mbuf *mbuf = NULL; 289c1d14583SBruce Richardson uint64_t dma_addr; 290c1d14583SBruce Richardson uint16_t i; 291c1d14583SBruce Richardson 292c1d14583SBruce Richardson for (i = 0; i < rxq->nb_rx_desc; i++) { 293c1d14583SBruce Richardson mbuf = rte_mbuf_raw_alloc(rxq->mp); 294c1d14583SBruce Richardson if (unlikely(!mbuf)) { 295c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to allocate mbuf for RX"); 296c1d14583SBruce Richardson return -ENOMEM; 297c1d14583SBruce Richardson } 298c1d14583SBruce Richardson 299c1d14583SBruce Richardson rte_mbuf_refcnt_set(mbuf, 1); 300c1d14583SBruce Richardson mbuf->next = NULL; 301c1d14583SBruce Richardson mbuf->data_off = RTE_PKTMBUF_HEADROOM; 302c1d14583SBruce Richardson mbuf->nb_segs = 1; 303c1d14583SBruce Richardson mbuf->port = rxq->port_id; 304c1d14583SBruce Richardson 305c1d14583SBruce Richardson dma_addr = 306c1d14583SBruce Richardson rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf)); 307c1d14583SBruce Richardson 308c1d14583SBruce Richardson rxd = &rxq->rx_ring[i]; 309c1d14583SBruce Richardson rxd->read.pkt_addr = dma_addr; 310c1d14583SBruce Richardson rxd->read.hdr_addr = 0; 311c1d14583SBruce Richardson #ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC 312c1d14583SBruce Richardson rxd->read.rsvd1 = 0; 313c1d14583SBruce Richardson rxd->read.rsvd2 = 0; 314c1d14583SBruce Richardson #endif 315c1d14583SBruce Richardson 316c1d14583SBruce Richardson rxq->sw_ring[i].mbuf = (void *)mbuf; 317c1d14583SBruce Richardson } 318c1d14583SBruce Richardson 319c1d14583SBruce Richardson return 0; 320c1d14583SBruce Richardson } 321c1d14583SBruce Richardson 322c1d14583SBruce Richardson static int 323c1d14583SBruce Richardson ice_dcf_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) 324c1d14583SBruce Richardson { 325c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 326c1d14583SBruce Richardson struct iavf_hw *hw = &ad->real_hw.avf; 327c1d14583SBruce Richardson struct ice_rx_queue *rxq; 328c1d14583SBruce Richardson int err = 0; 329c1d14583SBruce Richardson 330c1d14583SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) 331c1d14583SBruce Richardson return -EINVAL; 332c1d14583SBruce Richardson 333c1d14583SBruce Richardson rxq = dev->data->rx_queues[rx_queue_id]; 334c1d14583SBruce Richardson 335c1d14583SBruce Richardson err = alloc_rxq_mbufs(rxq); 336c1d14583SBruce Richardson if (err) { 337c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to allocate RX queue mbuf"); 338c1d14583SBruce Richardson return err; 339c1d14583SBruce Richardson } 340c1d14583SBruce Richardson 341c1d14583SBruce Richardson rte_wmb(); 342c1d14583SBruce Richardson 343c1d14583SBruce Richardson /* Init the RX tail register. */ 344c1d14583SBruce Richardson IAVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1); 345c1d14583SBruce Richardson IAVF_WRITE_FLUSH(hw); 346c1d14583SBruce Richardson 347c1d14583SBruce Richardson /* Ready to switch the queue on */ 348c1d14583SBruce Richardson err = ice_dcf_switch_queue(&ad->real_hw, rx_queue_id, true, true); 349c1d14583SBruce Richardson if (err) { 350c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to switch RX queue %u on", 351c1d14583SBruce Richardson rx_queue_id); 352c1d14583SBruce Richardson return err; 353c1d14583SBruce Richardson } 354c1d14583SBruce Richardson 355c1d14583SBruce Richardson dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; 356c1d14583SBruce Richardson 357c1d14583SBruce Richardson return 0; 358c1d14583SBruce Richardson } 359c1d14583SBruce Richardson 360c1d14583SBruce Richardson static inline void 361c1d14583SBruce Richardson reset_rx_queue(struct ice_rx_queue *rxq) 362c1d14583SBruce Richardson { 363c1d14583SBruce Richardson uint16_t len; 364c1d14583SBruce Richardson uint32_t i; 365c1d14583SBruce Richardson 366c1d14583SBruce Richardson if (!rxq) 367c1d14583SBruce Richardson return; 368c1d14583SBruce Richardson 369c1d14583SBruce Richardson len = rxq->nb_rx_desc + ICE_RX_MAX_BURST; 370c1d14583SBruce Richardson 371c1d14583SBruce Richardson for (i = 0; i < len * sizeof(union ice_rx_flex_desc); i++) 372c1d14583SBruce Richardson ((volatile char *)rxq->rx_ring)[i] = 0; 373c1d14583SBruce Richardson 374c1d14583SBruce Richardson memset(&rxq->fake_mbuf, 0x0, sizeof(rxq->fake_mbuf)); 375c1d14583SBruce Richardson 376c1d14583SBruce Richardson for (i = 0; i < ICE_RX_MAX_BURST; i++) 377c1d14583SBruce Richardson rxq->sw_ring[rxq->nb_rx_desc + i].mbuf = &rxq->fake_mbuf; 378c1d14583SBruce Richardson 379c1d14583SBruce Richardson /* for rx bulk */ 380c1d14583SBruce Richardson rxq->rx_nb_avail = 0; 381c1d14583SBruce Richardson rxq->rx_next_avail = 0; 382c1d14583SBruce Richardson rxq->rx_free_trigger = (uint16_t)(rxq->rx_free_thresh - 1); 383c1d14583SBruce Richardson 384c1d14583SBruce Richardson rxq->rx_tail = 0; 385c1d14583SBruce Richardson rxq->nb_rx_hold = 0; 386c1d14583SBruce Richardson rxq->pkt_first_seg = NULL; 387c1d14583SBruce Richardson rxq->pkt_last_seg = NULL; 388c1d14583SBruce Richardson } 389c1d14583SBruce Richardson 390c1d14583SBruce Richardson static inline void 391c038157aSBruce Richardson reset_tx_queue(struct ci_tx_queue *txq) 392c1d14583SBruce Richardson { 3935cc9919fSBruce Richardson struct ci_tx_entry *txe; 394c1d14583SBruce Richardson uint32_t i, size; 395c1d14583SBruce Richardson uint16_t prev; 396c1d14583SBruce Richardson 397c1d14583SBruce Richardson if (!txq) { 398c1d14583SBruce Richardson PMD_DRV_LOG(DEBUG, "Pointer to txq is NULL"); 399c1d14583SBruce Richardson return; 400c1d14583SBruce Richardson } 401c1d14583SBruce Richardson 402c1d14583SBruce Richardson txe = txq->sw_ring; 403c1d14583SBruce Richardson size = sizeof(struct ice_tx_desc) * txq->nb_tx_desc; 404c1d14583SBruce Richardson for (i = 0; i < size; i++) 4054d0f54d9SBruce Richardson ((volatile char *)txq->ice_tx_ring)[i] = 0; 406c1d14583SBruce Richardson 407c1d14583SBruce Richardson prev = (uint16_t)(txq->nb_tx_desc - 1); 408c1d14583SBruce Richardson for (i = 0; i < txq->nb_tx_desc; i++) { 4094d0f54d9SBruce Richardson txq->ice_tx_ring[i].cmd_type_offset_bsz = 410c1d14583SBruce Richardson rte_cpu_to_le_64(IAVF_TX_DESC_DTYPE_DESC_DONE); 411c1d14583SBruce Richardson txe[i].mbuf = NULL; 412c1d14583SBruce Richardson txe[i].last_id = i; 413c1d14583SBruce Richardson txe[prev].next_id = i; 414c1d14583SBruce Richardson prev = i; 415c1d14583SBruce Richardson } 416c1d14583SBruce Richardson 417c1d14583SBruce Richardson txq->tx_tail = 0; 418c1d14583SBruce Richardson txq->nb_tx_used = 0; 419c1d14583SBruce Richardson 420c1d14583SBruce Richardson txq->last_desc_cleaned = txq->nb_tx_desc - 1; 421c1d14583SBruce Richardson txq->nb_tx_free = txq->nb_tx_desc - 1; 422c1d14583SBruce Richardson 423c1d14583SBruce Richardson txq->tx_next_dd = txq->tx_rs_thresh - 1; 424c1d14583SBruce Richardson txq->tx_next_rs = txq->tx_rs_thresh - 1; 425c1d14583SBruce Richardson } 426c1d14583SBruce Richardson 427c1d14583SBruce Richardson static int 428c1d14583SBruce Richardson ice_dcf_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) 429c1d14583SBruce Richardson { 430c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 431c1d14583SBruce Richardson struct ice_dcf_hw *hw = &ad->real_hw; 432c1d14583SBruce Richardson struct ice_rx_queue *rxq; 433c1d14583SBruce Richardson int err; 434c1d14583SBruce Richardson 435c1d14583SBruce Richardson if (rx_queue_id >= dev->data->nb_rx_queues) 436c1d14583SBruce Richardson return -EINVAL; 437c1d14583SBruce Richardson 438c1d14583SBruce Richardson err = ice_dcf_switch_queue(hw, rx_queue_id, true, false); 439c1d14583SBruce Richardson if (err) { 440c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to switch RX queue %u off", 441c1d14583SBruce Richardson rx_queue_id); 442c1d14583SBruce Richardson return err; 443c1d14583SBruce Richardson } 444c1d14583SBruce Richardson 445c1d14583SBruce Richardson rxq = dev->data->rx_queues[rx_queue_id]; 446c1d14583SBruce Richardson rxq->rx_rel_mbufs(rxq); 447c1d14583SBruce Richardson reset_rx_queue(rxq); 448c1d14583SBruce Richardson dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; 449c1d14583SBruce Richardson 450c1d14583SBruce Richardson return 0; 451c1d14583SBruce Richardson } 452c1d14583SBruce Richardson 453c1d14583SBruce Richardson static int 454c1d14583SBruce Richardson ice_dcf_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) 455c1d14583SBruce Richardson { 456c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 457c1d14583SBruce Richardson struct iavf_hw *hw = &ad->real_hw.avf; 458c038157aSBruce Richardson struct ci_tx_queue *txq; 459c1d14583SBruce Richardson int err = 0; 460c1d14583SBruce Richardson 461c1d14583SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) 462c1d14583SBruce Richardson return -EINVAL; 463c1d14583SBruce Richardson 464c1d14583SBruce Richardson txq = dev->data->tx_queues[tx_queue_id]; 465c1d14583SBruce Richardson 466c1d14583SBruce Richardson /* Init the RX tail register. */ 467c1d14583SBruce Richardson txq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(tx_queue_id); 468c1d14583SBruce Richardson IAVF_PCI_REG_WRITE(txq->qtx_tail, 0); 469c1d14583SBruce Richardson IAVF_WRITE_FLUSH(hw); 470c1d14583SBruce Richardson 471c1d14583SBruce Richardson /* Ready to switch the queue on */ 472c1d14583SBruce Richardson err = ice_dcf_switch_queue(&ad->real_hw, tx_queue_id, false, true); 473c1d14583SBruce Richardson 474c1d14583SBruce Richardson if (err) { 475c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to switch TX queue %u on", 476c1d14583SBruce Richardson tx_queue_id); 477c1d14583SBruce Richardson return err; 478c1d14583SBruce Richardson } 479c1d14583SBruce Richardson 480c1d14583SBruce Richardson dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; 481c1d14583SBruce Richardson 482c1d14583SBruce Richardson return 0; 483c1d14583SBruce Richardson } 484c1d14583SBruce Richardson 485c1d14583SBruce Richardson static int 486c1d14583SBruce Richardson ice_dcf_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) 487c1d14583SBruce Richardson { 488c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 489c1d14583SBruce Richardson struct ice_dcf_hw *hw = &ad->real_hw; 490c038157aSBruce Richardson struct ci_tx_queue *txq; 491c1d14583SBruce Richardson int err; 492c1d14583SBruce Richardson 493c1d14583SBruce Richardson if (tx_queue_id >= dev->data->nb_tx_queues) 494c1d14583SBruce Richardson return -EINVAL; 495c1d14583SBruce Richardson 496c1d14583SBruce Richardson err = ice_dcf_switch_queue(hw, tx_queue_id, false, false); 497c1d14583SBruce Richardson if (err) { 498c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to switch TX queue %u off", 499c1d14583SBruce Richardson tx_queue_id); 500c1d14583SBruce Richardson return err; 501c1d14583SBruce Richardson } 502c1d14583SBruce Richardson 503c1d14583SBruce Richardson txq = dev->data->tx_queues[tx_queue_id]; 504*cef05386SBruce Richardson ci_txq_release_all_mbufs(txq, false); 505c1d14583SBruce Richardson reset_tx_queue(txq); 506c1d14583SBruce Richardson dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; 507c1d14583SBruce Richardson 508c1d14583SBruce Richardson return 0; 509c1d14583SBruce Richardson } 510c1d14583SBruce Richardson 511c1d14583SBruce Richardson static int 512c1d14583SBruce Richardson ice_dcf_start_queues(struct rte_eth_dev *dev) 513c1d14583SBruce Richardson { 514c1d14583SBruce Richardson struct ice_rx_queue *rxq; 515c038157aSBruce Richardson struct ci_tx_queue *txq; 516c1d14583SBruce Richardson int nb_rxq = 0; 517c1d14583SBruce Richardson int nb_txq, i; 518c1d14583SBruce Richardson 519c1d14583SBruce Richardson for (nb_txq = 0; nb_txq < dev->data->nb_tx_queues; nb_txq++) { 520c1d14583SBruce Richardson txq = dev->data->tx_queues[nb_txq]; 521c1d14583SBruce Richardson if (txq->tx_deferred_start) 522c1d14583SBruce Richardson continue; 523c1d14583SBruce Richardson if (ice_dcf_tx_queue_start(dev, nb_txq) != 0) { 524c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Fail to start queue %u", nb_txq); 525c1d14583SBruce Richardson goto tx_err; 526c1d14583SBruce Richardson } 527c1d14583SBruce Richardson } 528c1d14583SBruce Richardson 529c1d14583SBruce Richardson for (nb_rxq = 0; nb_rxq < dev->data->nb_rx_queues; nb_rxq++) { 530c1d14583SBruce Richardson rxq = dev->data->rx_queues[nb_rxq]; 531c1d14583SBruce Richardson if (rxq->rx_deferred_start) 532c1d14583SBruce Richardson continue; 533c1d14583SBruce Richardson if (ice_dcf_rx_queue_start(dev, nb_rxq) != 0) { 534c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Fail to start queue %u", nb_rxq); 535c1d14583SBruce Richardson goto rx_err; 536c1d14583SBruce Richardson } 537c1d14583SBruce Richardson } 538c1d14583SBruce Richardson 539c1d14583SBruce Richardson return 0; 540c1d14583SBruce Richardson 541c1d14583SBruce Richardson /* stop the started queues if failed to start all queues */ 542c1d14583SBruce Richardson rx_err: 543c1d14583SBruce Richardson for (i = 0; i < nb_rxq; i++) 544c1d14583SBruce Richardson ice_dcf_rx_queue_stop(dev, i); 545c1d14583SBruce Richardson tx_err: 546c1d14583SBruce Richardson for (i = 0; i < nb_txq; i++) 547c1d14583SBruce Richardson ice_dcf_tx_queue_stop(dev, i); 548c1d14583SBruce Richardson 549c1d14583SBruce Richardson return -1; 550c1d14583SBruce Richardson } 551c1d14583SBruce Richardson 552c1d14583SBruce Richardson static int 553c1d14583SBruce Richardson ice_dcf_dev_start(struct rte_eth_dev *dev) 554c1d14583SBruce Richardson { 555c1d14583SBruce Richardson struct ice_dcf_adapter *dcf_ad = dev->data->dev_private; 556c1d14583SBruce Richardson struct rte_intr_handle *intr_handle = dev->intr_handle; 557c1d14583SBruce Richardson struct ice_adapter *ad = &dcf_ad->parent; 558c1d14583SBruce Richardson struct ice_dcf_hw *hw = &dcf_ad->real_hw; 559c1d14583SBruce Richardson int ret; 560c1d14583SBruce Richardson 561c1d14583SBruce Richardson if (hw->resetting) { 562c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 563c1d14583SBruce Richardson "The DCF has been reset by PF, please reinit first"); 564c1d14583SBruce Richardson return -EIO; 565c1d14583SBruce Richardson } 566c1d14583SBruce Richardson 567c1d14583SBruce Richardson if (hw->tm_conf.root && !hw->tm_conf.committed) { 568c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 569c1d14583SBruce Richardson "please call hierarchy_commit() before starting the port"); 570c1d14583SBruce Richardson return -EIO; 571c1d14583SBruce Richardson } 572c1d14583SBruce Richardson 573c1d14583SBruce Richardson ad->pf.adapter_stopped = 0; 574c1d14583SBruce Richardson 575c1d14583SBruce Richardson hw->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues, 576c1d14583SBruce Richardson dev->data->nb_tx_queues); 577c1d14583SBruce Richardson 578c1d14583SBruce Richardson ret = ice_dcf_init_rx_queues(dev); 579c1d14583SBruce Richardson if (ret) { 580c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Fail to init queues"); 581c1d14583SBruce Richardson return ret; 582c1d14583SBruce Richardson } 583c1d14583SBruce Richardson 584c1d14583SBruce Richardson if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) { 585c1d14583SBruce Richardson ret = ice_dcf_init_rss(hw); 586c1d14583SBruce Richardson if (ret) { 587c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to configure RSS"); 588c1d14583SBruce Richardson return ret; 589c1d14583SBruce Richardson } 590c1d14583SBruce Richardson } 591c1d14583SBruce Richardson 592c1d14583SBruce Richardson ret = ice_dcf_configure_queues(hw); 593c1d14583SBruce Richardson if (ret) { 594c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Fail to config queues"); 595c1d14583SBruce Richardson return ret; 596c1d14583SBruce Richardson } 597c1d14583SBruce Richardson 598c1d14583SBruce Richardson ret = ice_dcf_config_rx_queues_irqs(dev, intr_handle); 599c1d14583SBruce Richardson if (ret) { 600c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Fail to config rx queues' irqs"); 601c1d14583SBruce Richardson return ret; 602c1d14583SBruce Richardson } 603c1d14583SBruce Richardson 604c1d14583SBruce Richardson if (dev->data->dev_conf.intr_conf.rxq != 0) { 605c1d14583SBruce Richardson rte_intr_disable(intr_handle); 606c1d14583SBruce Richardson rte_intr_enable(intr_handle); 607c1d14583SBruce Richardson } 608c1d14583SBruce Richardson 609c1d14583SBruce Richardson ret = ice_dcf_start_queues(dev); 610c1d14583SBruce Richardson if (ret) { 611c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to enable queues"); 612c1d14583SBruce Richardson return ret; 613c1d14583SBruce Richardson } 614c1d14583SBruce Richardson 615c1d14583SBruce Richardson ret = ice_dcf_add_del_all_mac_addr(hw, hw->eth_dev->data->mac_addrs, 616c1d14583SBruce Richardson true, VIRTCHNL_ETHER_ADDR_PRIMARY); 617c1d14583SBruce Richardson if (ret) { 618c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to add mac addr"); 619c1d14583SBruce Richardson return ret; 620c1d14583SBruce Richardson } 621c1d14583SBruce Richardson 622c1d14583SBruce Richardson if (dcf_ad->mc_addrs_num) { 623c1d14583SBruce Richardson /* flush previous addresses */ 624c1d14583SBruce Richardson ret = dcf_add_del_mc_addr_list(hw, dcf_ad->mc_addrs, 625c1d14583SBruce Richardson dcf_ad->mc_addrs_num, true); 626c1d14583SBruce Richardson if (ret) 627c1d14583SBruce Richardson return ret; 628c1d14583SBruce Richardson } 629c1d14583SBruce Richardson 630c1d14583SBruce Richardson 631c1d14583SBruce Richardson dev->data->dev_link.link_status = RTE_ETH_LINK_UP; 632c1d14583SBruce Richardson 633c1d14583SBruce Richardson return 0; 634c1d14583SBruce Richardson } 635c1d14583SBruce Richardson 636c1d14583SBruce Richardson static void 637c1d14583SBruce Richardson ice_dcf_stop_queues(struct rte_eth_dev *dev) 638c1d14583SBruce Richardson { 639c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 640c1d14583SBruce Richardson struct ice_dcf_hw *hw = &ad->real_hw; 641c1d14583SBruce Richardson struct ice_rx_queue *rxq; 642c038157aSBruce Richardson struct ci_tx_queue *txq; 643c1d14583SBruce Richardson int ret, i; 644c1d14583SBruce Richardson 645c1d14583SBruce Richardson /* Stop All queues */ 646c1d14583SBruce Richardson ret = ice_dcf_disable_queues(hw); 647c1d14583SBruce Richardson if (ret) 648c1d14583SBruce Richardson PMD_DRV_LOG(WARNING, "Fail to stop queues"); 649c1d14583SBruce Richardson 650c1d14583SBruce Richardson for (i = 0; i < dev->data->nb_tx_queues; i++) { 651c1d14583SBruce Richardson txq = dev->data->tx_queues[i]; 652c1d14583SBruce Richardson if (!txq) 653c1d14583SBruce Richardson continue; 654*cef05386SBruce Richardson ci_txq_release_all_mbufs(txq, false); 655c1d14583SBruce Richardson reset_tx_queue(txq); 656c1d14583SBruce Richardson dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 657c1d14583SBruce Richardson } 658c1d14583SBruce Richardson for (i = 0; i < dev->data->nb_rx_queues; i++) { 659c1d14583SBruce Richardson rxq = dev->data->rx_queues[i]; 660c1d14583SBruce Richardson if (!rxq) 661c1d14583SBruce Richardson continue; 662c1d14583SBruce Richardson rxq->rx_rel_mbufs(rxq); 663c1d14583SBruce Richardson reset_rx_queue(rxq); 664c1d14583SBruce Richardson dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 665c1d14583SBruce Richardson } 666c1d14583SBruce Richardson } 667c1d14583SBruce Richardson 668c1d14583SBruce Richardson static int 669c1d14583SBruce Richardson ice_dcf_dev_stop(struct rte_eth_dev *dev) 670c1d14583SBruce Richardson { 671c1d14583SBruce Richardson struct ice_dcf_adapter *dcf_ad = dev->data->dev_private; 672c1d14583SBruce Richardson struct rte_intr_handle *intr_handle = dev->intr_handle; 673c1d14583SBruce Richardson struct ice_adapter *ad = &dcf_ad->parent; 674c1d14583SBruce Richardson 675c1d14583SBruce Richardson if (ad->pf.adapter_stopped == 1) { 676c1d14583SBruce Richardson PMD_DRV_LOG(DEBUG, "Port is already stopped"); 677c1d14583SBruce Richardson return 0; 678c1d14583SBruce Richardson } 679c1d14583SBruce Richardson 680c1d14583SBruce Richardson /* Stop the VF representors for this device */ 681c1d14583SBruce Richardson ice_dcf_vf_repr_stop_all(dcf_ad); 682c1d14583SBruce Richardson 683c1d14583SBruce Richardson ice_dcf_stop_queues(dev); 684c1d14583SBruce Richardson 685c1d14583SBruce Richardson rte_intr_efd_disable(intr_handle); 686c1d14583SBruce Richardson rte_intr_vec_list_free(intr_handle); 687c1d14583SBruce Richardson 688c1d14583SBruce Richardson ice_dcf_add_del_all_mac_addr(&dcf_ad->real_hw, 689c1d14583SBruce Richardson dcf_ad->real_hw.eth_dev->data->mac_addrs, 690c1d14583SBruce Richardson false, VIRTCHNL_ETHER_ADDR_PRIMARY); 691c1d14583SBruce Richardson 692c1d14583SBruce Richardson if (dcf_ad->mc_addrs_num) 693c1d14583SBruce Richardson /* flush previous addresses */ 694c1d14583SBruce Richardson (void)dcf_add_del_mc_addr_list(&dcf_ad->real_hw, 695c1d14583SBruce Richardson dcf_ad->mc_addrs, 696c1d14583SBruce Richardson dcf_ad->mc_addrs_num, false); 697c1d14583SBruce Richardson 698c1d14583SBruce Richardson dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN; 699c1d14583SBruce Richardson ad->pf.adapter_stopped = 1; 700c1d14583SBruce Richardson 701c1d14583SBruce Richardson return 0; 702c1d14583SBruce Richardson } 703c1d14583SBruce Richardson 704c1d14583SBruce Richardson static int 705c1d14583SBruce Richardson ice_dcf_dev_configure(struct rte_eth_dev *dev) 706c1d14583SBruce Richardson { 707c1d14583SBruce Richardson struct ice_dcf_adapter *dcf_ad = dev->data->dev_private; 708c1d14583SBruce Richardson struct ice_adapter *ad = &dcf_ad->parent; 709c1d14583SBruce Richardson 710c1d14583SBruce Richardson ad->rx_bulk_alloc_allowed = true; 711c1d14583SBruce Richardson ad->tx_simple_allowed = true; 712c1d14583SBruce Richardson 713c1d14583SBruce Richardson if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) 714c1d14583SBruce Richardson dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH; 715c1d14583SBruce Richardson 716c1d14583SBruce Richardson return 0; 717c1d14583SBruce Richardson } 718c1d14583SBruce Richardson 719c1d14583SBruce Richardson static int 720c1d14583SBruce Richardson ice_dcf_dev_info_get(struct rte_eth_dev *dev, 721c1d14583SBruce Richardson struct rte_eth_dev_info *dev_info) 722c1d14583SBruce Richardson { 723c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 724c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 725c1d14583SBruce Richardson 726c1d14583SBruce Richardson dev_info->max_mac_addrs = DCF_NUM_MACADDR_MAX; 727c1d14583SBruce Richardson dev_info->max_rx_queues = hw->vsi_res->num_queue_pairs; 728c1d14583SBruce Richardson dev_info->max_tx_queues = hw->vsi_res->num_queue_pairs; 729c1d14583SBruce Richardson dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN; 730c1d14583SBruce Richardson dev_info->max_rx_pktlen = ICE_FRAME_SIZE_MAX; 731c1d14583SBruce Richardson dev_info->hash_key_size = hw->vf_res->rss_key_size; 732c1d14583SBruce Richardson dev_info->reta_size = hw->vf_res->rss_lut_size; 733c1d14583SBruce Richardson dev_info->flow_type_rss_offloads = ICE_RSS_OFFLOAD_ALL; 734c1d14583SBruce Richardson dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP; 735c1d14583SBruce Richardson dev_info->max_mtu = dev_info->max_rx_pktlen - ICE_ETH_OVERHEAD; 736c1d14583SBruce Richardson dev_info->min_mtu = RTE_ETHER_MIN_MTU; 737c1d14583SBruce Richardson 738c1d14583SBruce Richardson dev_info->rx_offload_capa = 739c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_VLAN_STRIP | 740c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | 741c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_UDP_CKSUM | 742c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_TCP_CKSUM | 743c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM | 744c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_SCATTER | 745c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_VLAN_FILTER | 746c1d14583SBruce Richardson RTE_ETH_RX_OFFLOAD_RSS_HASH; 747c1d14583SBruce Richardson dev_info->tx_offload_capa = 748c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_VLAN_INSERT | 749c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | 750c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_UDP_CKSUM | 751c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_TCP_CKSUM | 752c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_SCTP_CKSUM | 753c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM | 754c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM | 755c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_TCP_TSO | 756c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO | 757c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO | 758c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO | 759c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | 760c1d14583SBruce Richardson RTE_ETH_TX_OFFLOAD_MULTI_SEGS; 761c1d14583SBruce Richardson 762c1d14583SBruce Richardson dev_info->default_rxconf = (struct rte_eth_rxconf) { 763c1d14583SBruce Richardson .rx_thresh = { 764c1d14583SBruce Richardson .pthresh = ICE_DEFAULT_RX_PTHRESH, 765c1d14583SBruce Richardson .hthresh = ICE_DEFAULT_RX_HTHRESH, 766c1d14583SBruce Richardson .wthresh = ICE_DEFAULT_RX_WTHRESH, 767c1d14583SBruce Richardson }, 768c1d14583SBruce Richardson .rx_free_thresh = ICE_DEFAULT_RX_FREE_THRESH, 769c1d14583SBruce Richardson .rx_drop_en = 0, 770c1d14583SBruce Richardson .offloads = 0, 771c1d14583SBruce Richardson }; 772c1d14583SBruce Richardson 773c1d14583SBruce Richardson dev_info->default_txconf = (struct rte_eth_txconf) { 774c1d14583SBruce Richardson .tx_thresh = { 775c1d14583SBruce Richardson .pthresh = ICE_DEFAULT_TX_PTHRESH, 776c1d14583SBruce Richardson .hthresh = ICE_DEFAULT_TX_HTHRESH, 777c1d14583SBruce Richardson .wthresh = ICE_DEFAULT_TX_WTHRESH, 778c1d14583SBruce Richardson }, 779c1d14583SBruce Richardson .tx_free_thresh = ICE_DEFAULT_TX_FREE_THRESH, 780c1d14583SBruce Richardson .tx_rs_thresh = ICE_DEFAULT_TX_RSBIT_THRESH, 781c1d14583SBruce Richardson .offloads = 0, 782c1d14583SBruce Richardson }; 783c1d14583SBruce Richardson 784c1d14583SBruce Richardson dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { 785c1d14583SBruce Richardson .nb_max = ICE_MAX_RING_DESC, 786c1d14583SBruce Richardson .nb_min = ICE_MIN_RING_DESC, 787c1d14583SBruce Richardson .nb_align = ICE_ALIGN_RING_DESC, 788c1d14583SBruce Richardson }; 789c1d14583SBruce Richardson 790c1d14583SBruce Richardson dev_info->tx_desc_lim = (struct rte_eth_desc_lim) { 791c1d14583SBruce Richardson .nb_max = ICE_MAX_RING_DESC, 792c1d14583SBruce Richardson .nb_min = ICE_MIN_RING_DESC, 793c1d14583SBruce Richardson .nb_align = ICE_ALIGN_RING_DESC, 794c1d14583SBruce Richardson }; 795c1d14583SBruce Richardson 796c1d14583SBruce Richardson return 0; 797c1d14583SBruce Richardson } 798c1d14583SBruce Richardson 799c1d14583SBruce Richardson static int 800c1d14583SBruce Richardson dcf_config_promisc(struct ice_dcf_adapter *adapter, 801c1d14583SBruce Richardson bool enable_unicast, 802c1d14583SBruce Richardson bool enable_multicast) 803c1d14583SBruce Richardson { 804c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 805c1d14583SBruce Richardson struct virtchnl_promisc_info promisc; 806c1d14583SBruce Richardson struct dcf_virtchnl_cmd args; 807c1d14583SBruce Richardson int err; 808c1d14583SBruce Richardson 809c1d14583SBruce Richardson promisc.flags = 0; 810c1d14583SBruce Richardson promisc.vsi_id = hw->vsi_res->vsi_id; 811c1d14583SBruce Richardson 812c1d14583SBruce Richardson if (enable_unicast) 813c1d14583SBruce Richardson promisc.flags |= FLAG_VF_UNICAST_PROMISC; 814c1d14583SBruce Richardson 815c1d14583SBruce Richardson if (enable_multicast) 816c1d14583SBruce Richardson promisc.flags |= FLAG_VF_MULTICAST_PROMISC; 817c1d14583SBruce Richardson 818c1d14583SBruce Richardson memset(&args, 0, sizeof(args)); 819c1d14583SBruce Richardson args.v_op = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE; 820c1d14583SBruce Richardson args.req_msg = (uint8_t *)&promisc; 821c1d14583SBruce Richardson args.req_msglen = sizeof(promisc); 822c1d14583SBruce Richardson 823c1d14583SBruce Richardson err = ice_dcf_execute_virtchnl_cmd(hw, &args); 824c1d14583SBruce Richardson if (err) { 825c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 826c1d14583SBruce Richardson "fail to execute command VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE"); 827c1d14583SBruce Richardson return err; 828c1d14583SBruce Richardson } 829c1d14583SBruce Richardson 830c1d14583SBruce Richardson adapter->promisc_unicast_enabled = enable_unicast; 831c1d14583SBruce Richardson adapter->promisc_multicast_enabled = enable_multicast; 832c1d14583SBruce Richardson return 0; 833c1d14583SBruce Richardson } 834c1d14583SBruce Richardson 835c1d14583SBruce Richardson static int 836c1d14583SBruce Richardson ice_dcf_dev_promiscuous_enable(__rte_unused struct rte_eth_dev *dev) 837c1d14583SBruce Richardson { 838c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 839c1d14583SBruce Richardson 840c1d14583SBruce Richardson if (adapter->promisc_unicast_enabled) { 841c1d14583SBruce Richardson PMD_DRV_LOG(INFO, "promiscuous has been enabled"); 842c1d14583SBruce Richardson return 0; 843c1d14583SBruce Richardson } 844c1d14583SBruce Richardson 845c1d14583SBruce Richardson return dcf_config_promisc(adapter, true, 846c1d14583SBruce Richardson adapter->promisc_multicast_enabled); 847c1d14583SBruce Richardson } 848c1d14583SBruce Richardson 849c1d14583SBruce Richardson static int 850c1d14583SBruce Richardson ice_dcf_dev_promiscuous_disable(__rte_unused struct rte_eth_dev *dev) 851c1d14583SBruce Richardson { 852c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 853c1d14583SBruce Richardson 854c1d14583SBruce Richardson if (!adapter->promisc_unicast_enabled) { 855c1d14583SBruce Richardson PMD_DRV_LOG(INFO, "promiscuous has been disabled"); 856c1d14583SBruce Richardson return 0; 857c1d14583SBruce Richardson } 858c1d14583SBruce Richardson 859c1d14583SBruce Richardson return dcf_config_promisc(adapter, false, 860c1d14583SBruce Richardson adapter->promisc_multicast_enabled); 861c1d14583SBruce Richardson } 862c1d14583SBruce Richardson 863c1d14583SBruce Richardson static int 864c1d14583SBruce Richardson ice_dcf_dev_allmulticast_enable(__rte_unused struct rte_eth_dev *dev) 865c1d14583SBruce Richardson { 866c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 867c1d14583SBruce Richardson 868c1d14583SBruce Richardson if (adapter->promisc_multicast_enabled) { 869c1d14583SBruce Richardson PMD_DRV_LOG(INFO, "allmulticast has been enabled"); 870c1d14583SBruce Richardson return 0; 871c1d14583SBruce Richardson } 872c1d14583SBruce Richardson 873c1d14583SBruce Richardson return dcf_config_promisc(adapter, adapter->promisc_unicast_enabled, 874c1d14583SBruce Richardson true); 875c1d14583SBruce Richardson } 876c1d14583SBruce Richardson 877c1d14583SBruce Richardson static int 878c1d14583SBruce Richardson ice_dcf_dev_allmulticast_disable(__rte_unused struct rte_eth_dev *dev) 879c1d14583SBruce Richardson { 880c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 881c1d14583SBruce Richardson 882c1d14583SBruce Richardson if (!adapter->promisc_multicast_enabled) { 883c1d14583SBruce Richardson PMD_DRV_LOG(INFO, "allmulticast has been disabled"); 884c1d14583SBruce Richardson return 0; 885c1d14583SBruce Richardson } 886c1d14583SBruce Richardson 887c1d14583SBruce Richardson return dcf_config_promisc(adapter, adapter->promisc_unicast_enabled, 888c1d14583SBruce Richardson false); 889c1d14583SBruce Richardson } 890c1d14583SBruce Richardson 891c1d14583SBruce Richardson static int 892c1d14583SBruce Richardson dcf_dev_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr, 893c1d14583SBruce Richardson __rte_unused uint32_t index, 894c1d14583SBruce Richardson __rte_unused uint32_t pool) 895c1d14583SBruce Richardson { 896c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 897c1d14583SBruce Richardson int err; 898c1d14583SBruce Richardson 899c1d14583SBruce Richardson if (rte_is_zero_ether_addr(addr)) { 900c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Invalid Ethernet Address"); 901c1d14583SBruce Richardson return -EINVAL; 902c1d14583SBruce Richardson } 903c1d14583SBruce Richardson 904c1d14583SBruce Richardson err = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, addr, true, 905c1d14583SBruce Richardson VIRTCHNL_ETHER_ADDR_EXTRA); 906c1d14583SBruce Richardson if (err) { 907c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to add MAC address"); 908c1d14583SBruce Richardson return err; 909c1d14583SBruce Richardson } 910c1d14583SBruce Richardson 911c1d14583SBruce Richardson return 0; 912c1d14583SBruce Richardson } 913c1d14583SBruce Richardson 914c1d14583SBruce Richardson static void 915c1d14583SBruce Richardson dcf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index) 916c1d14583SBruce Richardson { 917c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 918c1d14583SBruce Richardson struct rte_ether_addr *addr = &dev->data->mac_addrs[index]; 919c1d14583SBruce Richardson int err; 920c1d14583SBruce Richardson 921c1d14583SBruce Richardson err = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, addr, false, 922c1d14583SBruce Richardson VIRTCHNL_ETHER_ADDR_EXTRA); 923c1d14583SBruce Richardson if (err) 924c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to remove MAC address"); 925c1d14583SBruce Richardson } 926c1d14583SBruce Richardson 927c1d14583SBruce Richardson static int 928c1d14583SBruce Richardson dcf_add_del_mc_addr_list(struct ice_dcf_hw *hw, 929c1d14583SBruce Richardson struct rte_ether_addr *mc_addrs, 930c1d14583SBruce Richardson uint32_t mc_addrs_num, bool add) 931c1d14583SBruce Richardson { 932c1d14583SBruce Richardson struct virtchnl_ether_addr_list *list; 933c1d14583SBruce Richardson struct dcf_virtchnl_cmd args; 934c1d14583SBruce Richardson uint32_t i; 935c1d14583SBruce Richardson int len, err = 0; 936c1d14583SBruce Richardson 937c1d14583SBruce Richardson len = sizeof(struct virtchnl_ether_addr_list); 938c1d14583SBruce Richardson len += sizeof(struct virtchnl_ether_addr) * mc_addrs_num; 939c1d14583SBruce Richardson 940c1d14583SBruce Richardson list = rte_zmalloc(NULL, len, 0); 941c1d14583SBruce Richardson if (!list) { 942c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to allocate memory"); 943c1d14583SBruce Richardson return -ENOMEM; 944c1d14583SBruce Richardson } 945c1d14583SBruce Richardson 946c1d14583SBruce Richardson for (i = 0; i < mc_addrs_num; i++) { 947c1d14583SBruce Richardson memcpy(list->list[i].addr, mc_addrs[i].addr_bytes, 948c1d14583SBruce Richardson sizeof(list->list[i].addr)); 949c1d14583SBruce Richardson list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA; 950c1d14583SBruce Richardson } 951c1d14583SBruce Richardson 952c1d14583SBruce Richardson list->vsi_id = hw->vsi_res->vsi_id; 953c1d14583SBruce Richardson list->num_elements = mc_addrs_num; 954c1d14583SBruce Richardson 955c1d14583SBruce Richardson memset(&args, 0, sizeof(args)); 956c1d14583SBruce Richardson args.v_op = add ? VIRTCHNL_OP_ADD_ETH_ADDR : 957c1d14583SBruce Richardson VIRTCHNL_OP_DEL_ETH_ADDR; 958c1d14583SBruce Richardson args.req_msg = (uint8_t *)list; 959c1d14583SBruce Richardson args.req_msglen = len; 960c1d14583SBruce Richardson err = ice_dcf_execute_virtchnl_cmd(hw, &args); 961c1d14583SBruce Richardson if (err) 962c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to execute command %s", 963c1d14583SBruce Richardson add ? "OP_ADD_ETHER_ADDRESS" : 964c1d14583SBruce Richardson "OP_DEL_ETHER_ADDRESS"); 965c1d14583SBruce Richardson rte_free(list); 966c1d14583SBruce Richardson return err; 967c1d14583SBruce Richardson } 968c1d14583SBruce Richardson 969c1d14583SBruce Richardson static int 970c1d14583SBruce Richardson dcf_set_mc_addr_list(struct rte_eth_dev *dev, 971c1d14583SBruce Richardson struct rte_ether_addr *mc_addrs, 972c1d14583SBruce Richardson uint32_t mc_addrs_num) 973c1d14583SBruce Richardson { 974c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 975c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 976c1d14583SBruce Richardson uint32_t i; 977c1d14583SBruce Richardson int ret; 978c1d14583SBruce Richardson 979c1d14583SBruce Richardson 980c1d14583SBruce Richardson if (mc_addrs_num > DCF_NUM_MACADDR_MAX) { 981c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 982c1d14583SBruce Richardson "can't add more than a limited number (%u) of addresses.", 983c1d14583SBruce Richardson (uint32_t)DCF_NUM_MACADDR_MAX); 984c1d14583SBruce Richardson return -EINVAL; 985c1d14583SBruce Richardson } 986c1d14583SBruce Richardson 987c1d14583SBruce Richardson for (i = 0; i < mc_addrs_num; i++) { 988c1d14583SBruce Richardson if (!rte_is_multicast_ether_addr(&mc_addrs[i])) { 989c1d14583SBruce Richardson const uint8_t *mac = mc_addrs[i].addr_bytes; 990c1d14583SBruce Richardson 991c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 992c1d14583SBruce Richardson "Invalid mac: %02x:%02x:%02x:%02x:%02x:%02x", 993c1d14583SBruce Richardson mac[0], mac[1], mac[2], mac[3], mac[4], 994c1d14583SBruce Richardson mac[5]); 995c1d14583SBruce Richardson return -EINVAL; 996c1d14583SBruce Richardson } 997c1d14583SBruce Richardson } 998c1d14583SBruce Richardson 999c1d14583SBruce Richardson if (adapter->mc_addrs_num) { 1000c1d14583SBruce Richardson /* flush previous addresses */ 1001c1d14583SBruce Richardson ret = dcf_add_del_mc_addr_list(hw, adapter->mc_addrs, 1002c1d14583SBruce Richardson adapter->mc_addrs_num, false); 1003c1d14583SBruce Richardson if (ret) 1004c1d14583SBruce Richardson return ret; 1005c1d14583SBruce Richardson } 1006c1d14583SBruce Richardson if (!mc_addrs_num) { 1007c1d14583SBruce Richardson adapter->mc_addrs_num = 0; 1008c1d14583SBruce Richardson return 0; 1009c1d14583SBruce Richardson } 1010c1d14583SBruce Richardson 1011c1d14583SBruce Richardson /* add new ones */ 1012c1d14583SBruce Richardson ret = dcf_add_del_mc_addr_list(hw, mc_addrs, mc_addrs_num, true); 1013c1d14583SBruce Richardson if (ret) { 1014c1d14583SBruce Richardson /* if adding mac address list fails, should add the 1015c1d14583SBruce Richardson * previous addresses back. 1016c1d14583SBruce Richardson */ 1017c1d14583SBruce Richardson if (adapter->mc_addrs_num) 1018c1d14583SBruce Richardson (void)dcf_add_del_mc_addr_list(hw, adapter->mc_addrs, 1019c1d14583SBruce Richardson adapter->mc_addrs_num, 1020c1d14583SBruce Richardson true); 1021c1d14583SBruce Richardson return ret; 1022c1d14583SBruce Richardson } 1023c1d14583SBruce Richardson adapter->mc_addrs_num = mc_addrs_num; 1024c1d14583SBruce Richardson memcpy(adapter->mc_addrs, 1025c1d14583SBruce Richardson mc_addrs, mc_addrs_num * sizeof(*mc_addrs)); 1026c1d14583SBruce Richardson 1027c1d14583SBruce Richardson return 0; 1028c1d14583SBruce Richardson } 1029c1d14583SBruce Richardson 1030c1d14583SBruce Richardson static int 1031c1d14583SBruce Richardson dcf_dev_set_default_mac_addr(struct rte_eth_dev *dev, 1032c1d14583SBruce Richardson struct rte_ether_addr *mac_addr) 1033c1d14583SBruce Richardson { 1034c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1035c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1036c1d14583SBruce Richardson struct rte_ether_addr *old_addr; 1037c1d14583SBruce Richardson int ret; 1038c1d14583SBruce Richardson 1039c1d14583SBruce Richardson old_addr = hw->eth_dev->data->mac_addrs; 1040c1d14583SBruce Richardson if (rte_is_same_ether_addr(old_addr, mac_addr)) 1041c1d14583SBruce Richardson return 0; 1042c1d14583SBruce Richardson 1043c1d14583SBruce Richardson ret = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, old_addr, false, 1044c1d14583SBruce Richardson VIRTCHNL_ETHER_ADDR_PRIMARY); 1045c1d14583SBruce Richardson if (ret) 1046c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Fail to delete old MAC:" 1047c1d14583SBruce Richardson " %02X:%02X:%02X:%02X:%02X:%02X", 1048c1d14583SBruce Richardson old_addr->addr_bytes[0], 1049c1d14583SBruce Richardson old_addr->addr_bytes[1], 1050c1d14583SBruce Richardson old_addr->addr_bytes[2], 1051c1d14583SBruce Richardson old_addr->addr_bytes[3], 1052c1d14583SBruce Richardson old_addr->addr_bytes[4], 1053c1d14583SBruce Richardson old_addr->addr_bytes[5]); 1054c1d14583SBruce Richardson 1055c1d14583SBruce Richardson ret = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, mac_addr, true, 1056c1d14583SBruce Richardson VIRTCHNL_ETHER_ADDR_PRIMARY); 1057c1d14583SBruce Richardson if (ret) 1058c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Fail to add new MAC:" 1059c1d14583SBruce Richardson " %02X:%02X:%02X:%02X:%02X:%02X", 1060c1d14583SBruce Richardson mac_addr->addr_bytes[0], 1061c1d14583SBruce Richardson mac_addr->addr_bytes[1], 1062c1d14583SBruce Richardson mac_addr->addr_bytes[2], 1063c1d14583SBruce Richardson mac_addr->addr_bytes[3], 1064c1d14583SBruce Richardson mac_addr->addr_bytes[4], 1065c1d14583SBruce Richardson mac_addr->addr_bytes[5]); 1066c1d14583SBruce Richardson 1067c1d14583SBruce Richardson if (ret) 1068c1d14583SBruce Richardson return -EIO; 1069c1d14583SBruce Richardson 1070c1d14583SBruce Richardson rte_ether_addr_copy(mac_addr, hw->eth_dev->data->mac_addrs); 1071c1d14583SBruce Richardson return 0; 1072c1d14583SBruce Richardson } 1073c1d14583SBruce Richardson 1074c1d14583SBruce Richardson static int 1075c1d14583SBruce Richardson dcf_add_del_vlan_v2(struct ice_dcf_hw *hw, uint16_t vlanid, bool add) 1076c1d14583SBruce Richardson { 1077c1d14583SBruce Richardson struct virtchnl_vlan_supported_caps *supported_caps = 1078c1d14583SBruce Richardson &hw->vlan_v2_caps.filtering.filtering_support; 1079c1d14583SBruce Richardson struct virtchnl_vlan *vlan_setting; 1080c1d14583SBruce Richardson struct virtchnl_vlan_filter_list_v2 vlan_filter; 1081c1d14583SBruce Richardson struct dcf_virtchnl_cmd args; 1082c1d14583SBruce Richardson uint32_t filtering_caps; 1083c1d14583SBruce Richardson int err; 1084c1d14583SBruce Richardson 1085c1d14583SBruce Richardson if (supported_caps->outer) { 1086c1d14583SBruce Richardson filtering_caps = supported_caps->outer; 1087c1d14583SBruce Richardson vlan_setting = &vlan_filter.filters[0].outer; 1088c1d14583SBruce Richardson } else { 1089c1d14583SBruce Richardson filtering_caps = supported_caps->inner; 1090c1d14583SBruce Richardson vlan_setting = &vlan_filter.filters[0].inner; 1091c1d14583SBruce Richardson } 1092c1d14583SBruce Richardson 1093c1d14583SBruce Richardson if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100)) 1094c1d14583SBruce Richardson return -ENOTSUP; 1095c1d14583SBruce Richardson 1096c1d14583SBruce Richardson memset(&vlan_filter, 0, sizeof(vlan_filter)); 1097c1d14583SBruce Richardson vlan_filter.vport_id = hw->vsi_res->vsi_id; 1098c1d14583SBruce Richardson vlan_filter.num_elements = 1; 1099c1d14583SBruce Richardson vlan_setting->tpid = RTE_ETHER_TYPE_VLAN; 1100c1d14583SBruce Richardson vlan_setting->tci = vlanid; 1101c1d14583SBruce Richardson 1102c1d14583SBruce Richardson memset(&args, 0, sizeof(args)); 1103c1d14583SBruce Richardson args.v_op = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2; 1104c1d14583SBruce Richardson args.req_msg = (uint8_t *)&vlan_filter; 1105c1d14583SBruce Richardson args.req_msglen = sizeof(vlan_filter); 1106c1d14583SBruce Richardson err = ice_dcf_execute_virtchnl_cmd(hw, &args); 1107c1d14583SBruce Richardson if (err) 1108c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to execute command %s", 1109c1d14583SBruce Richardson add ? "OP_ADD_VLAN_V2" : "OP_DEL_VLAN_V2"); 1110c1d14583SBruce Richardson 1111c1d14583SBruce Richardson return err; 1112c1d14583SBruce Richardson } 1113c1d14583SBruce Richardson 1114c1d14583SBruce Richardson static int 1115c1d14583SBruce Richardson dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add) 1116c1d14583SBruce Richardson { 1117c1d14583SBruce Richardson struct virtchnl_vlan_filter_list *vlan_list; 1118c1d14583SBruce Richardson uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) + 1119c1d14583SBruce Richardson sizeof(uint16_t)]; 1120c1d14583SBruce Richardson struct dcf_virtchnl_cmd args; 1121c1d14583SBruce Richardson int err; 1122c1d14583SBruce Richardson 1123c1d14583SBruce Richardson vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer; 1124c1d14583SBruce Richardson vlan_list->vsi_id = hw->vsi_res->vsi_id; 1125c1d14583SBruce Richardson vlan_list->num_elements = 1; 1126c1d14583SBruce Richardson vlan_list->vlan_id[0] = vlanid; 1127c1d14583SBruce Richardson 1128c1d14583SBruce Richardson memset(&args, 0, sizeof(args)); 1129c1d14583SBruce Richardson args.v_op = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN; 1130c1d14583SBruce Richardson args.req_msg = cmd_buffer; 1131c1d14583SBruce Richardson args.req_msglen = sizeof(cmd_buffer); 1132c1d14583SBruce Richardson err = ice_dcf_execute_virtchnl_cmd(hw, &args); 1133c1d14583SBruce Richardson if (err) 1134c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to execute command %s", 1135c1d14583SBruce Richardson add ? "OP_ADD_VLAN" : "OP_DEL_VLAN"); 1136c1d14583SBruce Richardson 1137c1d14583SBruce Richardson return err; 1138c1d14583SBruce Richardson } 1139c1d14583SBruce Richardson 1140c1d14583SBruce Richardson static int 1141c1d14583SBruce Richardson dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) 1142c1d14583SBruce Richardson { 1143c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1144c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1145c1d14583SBruce Richardson int err; 1146c1d14583SBruce Richardson 1147c1d14583SBruce Richardson if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) { 1148c1d14583SBruce Richardson err = dcf_add_del_vlan_v2(hw, vlan_id, on); 1149c1d14583SBruce Richardson if (err) 1150c1d14583SBruce Richardson return -EIO; 1151c1d14583SBruce Richardson return 0; 1152c1d14583SBruce Richardson } 1153c1d14583SBruce Richardson 1154c1d14583SBruce Richardson if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) 1155c1d14583SBruce Richardson return -ENOTSUP; 1156c1d14583SBruce Richardson 1157c1d14583SBruce Richardson err = dcf_add_del_vlan(hw, vlan_id, on); 1158c1d14583SBruce Richardson if (err) 1159c1d14583SBruce Richardson return -EIO; 1160c1d14583SBruce Richardson return 0; 1161c1d14583SBruce Richardson } 1162c1d14583SBruce Richardson 1163c1d14583SBruce Richardson static void 1164c1d14583SBruce Richardson dcf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable) 1165c1d14583SBruce Richardson { 1166c1d14583SBruce Richardson struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf; 1167c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1168c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1169c1d14583SBruce Richardson uint32_t i, j; 1170c1d14583SBruce Richardson uint64_t ids; 1171c1d14583SBruce Richardson 1172c1d14583SBruce Richardson for (i = 0; i < RTE_DIM(vfc->ids); i++) { 1173c1d14583SBruce Richardson if (vfc->ids[i] == 0) 1174c1d14583SBruce Richardson continue; 1175c1d14583SBruce Richardson 1176c1d14583SBruce Richardson ids = vfc->ids[i]; 1177c1d14583SBruce Richardson for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) { 1178c1d14583SBruce Richardson if (ids & 1) 1179c1d14583SBruce Richardson dcf_add_del_vlan_v2(hw, 64 * i + j, enable); 1180c1d14583SBruce Richardson } 1181c1d14583SBruce Richardson } 1182c1d14583SBruce Richardson } 1183c1d14583SBruce Richardson 1184c1d14583SBruce Richardson static int 1185c1d14583SBruce Richardson dcf_config_vlan_strip_v2(struct ice_dcf_hw *hw, bool enable) 1186c1d14583SBruce Richardson { 1187c1d14583SBruce Richardson struct virtchnl_vlan_supported_caps *stripping_caps = 1188c1d14583SBruce Richardson &hw->vlan_v2_caps.offloads.stripping_support; 1189c1d14583SBruce Richardson struct virtchnl_vlan_setting vlan_strip; 1190c1d14583SBruce Richardson struct dcf_virtchnl_cmd args; 1191c1d14583SBruce Richardson uint32_t *ethertype; 1192c1d14583SBruce Richardson int ret; 1193c1d14583SBruce Richardson 1194c1d14583SBruce Richardson if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) && 1195c1d14583SBruce Richardson (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE)) 1196c1d14583SBruce Richardson ethertype = &vlan_strip.outer_ethertype_setting; 1197c1d14583SBruce Richardson else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) && 1198c1d14583SBruce Richardson (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE)) 1199c1d14583SBruce Richardson ethertype = &vlan_strip.inner_ethertype_setting; 1200c1d14583SBruce Richardson else 1201c1d14583SBruce Richardson return -ENOTSUP; 1202c1d14583SBruce Richardson 1203c1d14583SBruce Richardson memset(&vlan_strip, 0, sizeof(vlan_strip)); 1204c1d14583SBruce Richardson vlan_strip.vport_id = hw->vsi_res->vsi_id; 1205c1d14583SBruce Richardson *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100; 1206c1d14583SBruce Richardson 1207c1d14583SBruce Richardson memset(&args, 0, sizeof(args)); 1208c1d14583SBruce Richardson args.v_op = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 : 1209c1d14583SBruce Richardson VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2; 1210c1d14583SBruce Richardson args.req_msg = (uint8_t *)&vlan_strip; 1211c1d14583SBruce Richardson args.req_msglen = sizeof(vlan_strip); 1212c1d14583SBruce Richardson ret = ice_dcf_execute_virtchnl_cmd(hw, &args); 1213c1d14583SBruce Richardson if (ret) 1214c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to execute command %s", 1215c1d14583SBruce Richardson enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" : 1216c1d14583SBruce Richardson "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2"); 1217c1d14583SBruce Richardson 1218c1d14583SBruce Richardson return ret; 1219c1d14583SBruce Richardson } 1220c1d14583SBruce Richardson 1221c1d14583SBruce Richardson static int 1222c1d14583SBruce Richardson dcf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask) 1223c1d14583SBruce Richardson { 1224c1d14583SBruce Richardson struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; 1225c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1226c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1227c1d14583SBruce Richardson bool enable; 1228c1d14583SBruce Richardson int err; 1229c1d14583SBruce Richardson 1230c1d14583SBruce Richardson if (mask & RTE_ETH_VLAN_FILTER_MASK) { 1231c1d14583SBruce Richardson enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER); 1232c1d14583SBruce Richardson 1233c1d14583SBruce Richardson dcf_iterate_vlan_filters_v2(dev, enable); 1234c1d14583SBruce Richardson } 1235c1d14583SBruce Richardson 1236c1d14583SBruce Richardson if (mask & RTE_ETH_VLAN_STRIP_MASK) { 1237c1d14583SBruce Richardson enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP); 1238c1d14583SBruce Richardson 1239c1d14583SBruce Richardson err = dcf_config_vlan_strip_v2(hw, enable); 1240c1d14583SBruce Richardson /* If not support, the stripping is already disabled by PF */ 1241c1d14583SBruce Richardson if (err == -ENOTSUP && !enable) 1242c1d14583SBruce Richardson err = 0; 1243c1d14583SBruce Richardson if (err) 1244c1d14583SBruce Richardson return -EIO; 1245c1d14583SBruce Richardson } 1246c1d14583SBruce Richardson 1247c1d14583SBruce Richardson return 0; 1248c1d14583SBruce Richardson } 1249c1d14583SBruce Richardson 1250c1d14583SBruce Richardson static int 1251c1d14583SBruce Richardson dcf_enable_vlan_strip(struct ice_dcf_hw *hw) 1252c1d14583SBruce Richardson { 1253c1d14583SBruce Richardson struct dcf_virtchnl_cmd args; 1254c1d14583SBruce Richardson int ret; 1255c1d14583SBruce Richardson 1256c1d14583SBruce Richardson memset(&args, 0, sizeof(args)); 1257c1d14583SBruce Richardson args.v_op = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING; 1258c1d14583SBruce Richardson ret = ice_dcf_execute_virtchnl_cmd(hw, &args); 1259c1d14583SBruce Richardson if (ret) 1260c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 1261c1d14583SBruce Richardson "Failed to execute command of OP_ENABLE_VLAN_STRIPPING"); 1262c1d14583SBruce Richardson 1263c1d14583SBruce Richardson return ret; 1264c1d14583SBruce Richardson } 1265c1d14583SBruce Richardson 1266c1d14583SBruce Richardson static int 1267c1d14583SBruce Richardson dcf_disable_vlan_strip(struct ice_dcf_hw *hw) 1268c1d14583SBruce Richardson { 1269c1d14583SBruce Richardson struct dcf_virtchnl_cmd args; 1270c1d14583SBruce Richardson int ret; 1271c1d14583SBruce Richardson 1272c1d14583SBruce Richardson memset(&args, 0, sizeof(args)); 1273c1d14583SBruce Richardson args.v_op = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING; 1274c1d14583SBruce Richardson ret = ice_dcf_execute_virtchnl_cmd(hw, &args); 1275c1d14583SBruce Richardson if (ret) 1276c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 1277c1d14583SBruce Richardson "Failed to execute command of OP_DISABLE_VLAN_STRIPPING"); 1278c1d14583SBruce Richardson 1279c1d14583SBruce Richardson return ret; 1280c1d14583SBruce Richardson } 1281c1d14583SBruce Richardson 1282c1d14583SBruce Richardson static int 1283c1d14583SBruce Richardson dcf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) 1284c1d14583SBruce Richardson { 1285c1d14583SBruce Richardson struct rte_eth_conf *dev_conf = &dev->data->dev_conf; 1286c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1287c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1288c1d14583SBruce Richardson int err; 1289c1d14583SBruce Richardson 1290c1d14583SBruce Richardson if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) 1291c1d14583SBruce Richardson return dcf_dev_vlan_offload_set_v2(dev, mask); 1292c1d14583SBruce Richardson 1293c1d14583SBruce Richardson if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) 1294c1d14583SBruce Richardson return -ENOTSUP; 1295c1d14583SBruce Richardson 1296c1d14583SBruce Richardson /* Vlan stripping setting */ 1297c1d14583SBruce Richardson if (mask & RTE_ETH_VLAN_STRIP_MASK) { 1298c1d14583SBruce Richardson /* Enable or disable VLAN stripping */ 1299c1d14583SBruce Richardson if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) 1300c1d14583SBruce Richardson err = dcf_enable_vlan_strip(hw); 1301c1d14583SBruce Richardson else 1302c1d14583SBruce Richardson err = dcf_disable_vlan_strip(hw); 1303c1d14583SBruce Richardson 1304c1d14583SBruce Richardson if (err) 1305c1d14583SBruce Richardson return -EIO; 1306c1d14583SBruce Richardson } 1307c1d14583SBruce Richardson return 0; 1308c1d14583SBruce Richardson } 1309c1d14583SBruce Richardson 1310c1d14583SBruce Richardson static int 1311c1d14583SBruce Richardson ice_dcf_dev_flow_ops_get(struct rte_eth_dev *dev, 1312c1d14583SBruce Richardson const struct rte_flow_ops **ops) 1313c1d14583SBruce Richardson { 1314c1d14583SBruce Richardson if (!dev) 1315c1d14583SBruce Richardson return -EINVAL; 1316c1d14583SBruce Richardson 1317c1d14583SBruce Richardson *ops = &ice_flow_ops; 1318c1d14583SBruce Richardson return 0; 1319c1d14583SBruce Richardson } 1320c1d14583SBruce Richardson 1321c1d14583SBruce Richardson static int 1322c1d14583SBruce Richardson ice_dcf_dev_rss_reta_update(struct rte_eth_dev *dev, 1323c1d14583SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 1324c1d14583SBruce Richardson uint16_t reta_size) 1325c1d14583SBruce Richardson { 1326c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1327c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1328c1d14583SBruce Richardson uint8_t *lut; 1329c1d14583SBruce Richardson uint16_t i, idx, shift; 1330c1d14583SBruce Richardson int ret; 1331c1d14583SBruce Richardson 1332c1d14583SBruce Richardson if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) 1333c1d14583SBruce Richardson return -ENOTSUP; 1334c1d14583SBruce Richardson 1335c1d14583SBruce Richardson if (reta_size != hw->vf_res->rss_lut_size) { 1336c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "The size of hash lookup table configured " 1337c1d14583SBruce Richardson "(%d) doesn't match the number of hardware can " 1338c1d14583SBruce Richardson "support (%d)", reta_size, hw->vf_res->rss_lut_size); 1339c1d14583SBruce Richardson return -EINVAL; 1340c1d14583SBruce Richardson } 1341c1d14583SBruce Richardson 1342c1d14583SBruce Richardson lut = rte_zmalloc("rss_lut", reta_size, 0); 1343c1d14583SBruce Richardson if (!lut) { 1344c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "No memory can be allocated"); 1345c1d14583SBruce Richardson return -ENOMEM; 1346c1d14583SBruce Richardson } 1347c1d14583SBruce Richardson /* store the old lut table temporarily */ 1348c1d14583SBruce Richardson rte_memcpy(lut, hw->rss_lut, reta_size); 1349c1d14583SBruce Richardson 1350c1d14583SBruce Richardson for (i = 0; i < reta_size; i++) { 1351c1d14583SBruce Richardson idx = i / RTE_ETH_RETA_GROUP_SIZE; 1352c1d14583SBruce Richardson shift = i % RTE_ETH_RETA_GROUP_SIZE; 1353c1d14583SBruce Richardson if (reta_conf[idx].mask & (1ULL << shift)) 1354c1d14583SBruce Richardson lut[i] = reta_conf[idx].reta[shift]; 1355c1d14583SBruce Richardson } 1356c1d14583SBruce Richardson 1357c1d14583SBruce Richardson rte_memcpy(hw->rss_lut, lut, reta_size); 1358c1d14583SBruce Richardson /* send virtchnnl ops to configure rss*/ 1359c1d14583SBruce Richardson ret = ice_dcf_configure_rss_lut(hw); 1360c1d14583SBruce Richardson if (ret) /* revert back */ 1361c1d14583SBruce Richardson rte_memcpy(hw->rss_lut, lut, reta_size); 1362c1d14583SBruce Richardson rte_free(lut); 1363c1d14583SBruce Richardson 1364c1d14583SBruce Richardson return ret; 1365c1d14583SBruce Richardson } 1366c1d14583SBruce Richardson 1367c1d14583SBruce Richardson static int 1368c1d14583SBruce Richardson ice_dcf_dev_rss_reta_query(struct rte_eth_dev *dev, 1369c1d14583SBruce Richardson struct rte_eth_rss_reta_entry64 *reta_conf, 1370c1d14583SBruce Richardson uint16_t reta_size) 1371c1d14583SBruce Richardson { 1372c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1373c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1374c1d14583SBruce Richardson uint16_t i, idx, shift; 1375c1d14583SBruce Richardson 1376c1d14583SBruce Richardson if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) 1377c1d14583SBruce Richardson return -ENOTSUP; 1378c1d14583SBruce Richardson 1379c1d14583SBruce Richardson if (reta_size != hw->vf_res->rss_lut_size) { 1380c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "The size of hash lookup table configured " 1381c1d14583SBruce Richardson "(%d) doesn't match the number of hardware can " 1382c1d14583SBruce Richardson "support (%d)", reta_size, hw->vf_res->rss_lut_size); 1383c1d14583SBruce Richardson return -EINVAL; 1384c1d14583SBruce Richardson } 1385c1d14583SBruce Richardson 1386c1d14583SBruce Richardson for (i = 0; i < reta_size; i++) { 1387c1d14583SBruce Richardson idx = i / RTE_ETH_RETA_GROUP_SIZE; 1388c1d14583SBruce Richardson shift = i % RTE_ETH_RETA_GROUP_SIZE; 1389c1d14583SBruce Richardson if (reta_conf[idx].mask & (1ULL << shift)) 1390c1d14583SBruce Richardson reta_conf[idx].reta[shift] = hw->rss_lut[i]; 1391c1d14583SBruce Richardson } 1392c1d14583SBruce Richardson 1393c1d14583SBruce Richardson return 0; 1394c1d14583SBruce Richardson } 1395c1d14583SBruce Richardson 1396c1d14583SBruce Richardson static int 1397c1d14583SBruce Richardson ice_dcf_dev_rss_hash_update(struct rte_eth_dev *dev, 1398c1d14583SBruce Richardson struct rte_eth_rss_conf *rss_conf) 1399c1d14583SBruce Richardson { 1400c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1401c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1402c1d14583SBruce Richardson int ret; 1403c1d14583SBruce Richardson 1404c1d14583SBruce Richardson if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) 1405c1d14583SBruce Richardson return -ENOTSUP; 1406c1d14583SBruce Richardson 1407c1d14583SBruce Richardson /* HENA setting, it is enabled by default, no change */ 1408c1d14583SBruce Richardson if (!rss_conf->rss_key || rss_conf->rss_key_len == 0) { 1409c1d14583SBruce Richardson PMD_DRV_LOG(DEBUG, "No key to be configured"); 1410c1d14583SBruce Richardson return 0; 1411c1d14583SBruce Richardson } else if (rss_conf->rss_key_len != hw->vf_res->rss_key_size) { 1412c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "The size of hash key configured " 1413c1d14583SBruce Richardson "(%d) doesn't match the size of hardware can " 1414c1d14583SBruce Richardson "support (%d)", rss_conf->rss_key_len, 1415c1d14583SBruce Richardson hw->vf_res->rss_key_size); 1416c1d14583SBruce Richardson return -EINVAL; 1417c1d14583SBruce Richardson } 1418c1d14583SBruce Richardson 1419c1d14583SBruce Richardson rte_memcpy(hw->rss_key, rss_conf->rss_key, rss_conf->rss_key_len); 1420c1d14583SBruce Richardson 1421c1d14583SBruce Richardson ret = ice_dcf_configure_rss_key(hw); 1422c1d14583SBruce Richardson if (ret) 1423c1d14583SBruce Richardson return ret; 1424c1d14583SBruce Richardson 1425c1d14583SBruce Richardson /* Clear existing RSS. */ 1426c1d14583SBruce Richardson ret = ice_dcf_set_hena(hw, 0); 1427c1d14583SBruce Richardson 1428c1d14583SBruce Richardson /* It is a workaround, temporarily allow error to be returned 1429c1d14583SBruce Richardson * due to possible lack of PF handling for hena = 0. 1430c1d14583SBruce Richardson */ 1431c1d14583SBruce Richardson if (ret) 1432c1d14583SBruce Richardson PMD_DRV_LOG(WARNING, "fail to clean existing RSS," 1433c1d14583SBruce Richardson "lack PF support"); 1434c1d14583SBruce Richardson 1435c1d14583SBruce Richardson /* Set new RSS configuration. */ 1436c1d14583SBruce Richardson ret = ice_dcf_rss_hash_set(hw, rss_conf->rss_hf, true); 1437c1d14583SBruce Richardson if (ret) { 1438c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "fail to set new RSS"); 1439c1d14583SBruce Richardson return ret; 1440c1d14583SBruce Richardson } 1441c1d14583SBruce Richardson 1442c1d14583SBruce Richardson return 0; 1443c1d14583SBruce Richardson } 1444c1d14583SBruce Richardson 1445c1d14583SBruce Richardson static int 1446c1d14583SBruce Richardson ice_dcf_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 1447c1d14583SBruce Richardson struct rte_eth_rss_conf *rss_conf) 1448c1d14583SBruce Richardson { 1449c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1450c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1451c1d14583SBruce Richardson 1452c1d14583SBruce Richardson if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) 1453c1d14583SBruce Richardson return -ENOTSUP; 1454c1d14583SBruce Richardson 1455c1d14583SBruce Richardson /* Just set it to default value now. */ 1456c1d14583SBruce Richardson rss_conf->rss_hf = ICE_RSS_OFFLOAD_ALL; 1457c1d14583SBruce Richardson 1458c1d14583SBruce Richardson if (!rss_conf->rss_key) 1459c1d14583SBruce Richardson return 0; 1460c1d14583SBruce Richardson 1461c1d14583SBruce Richardson rss_conf->rss_key_len = hw->vf_res->rss_key_size; 1462c1d14583SBruce Richardson rte_memcpy(rss_conf->rss_key, hw->rss_key, rss_conf->rss_key_len); 1463c1d14583SBruce Richardson 1464c1d14583SBruce Richardson return 0; 1465c1d14583SBruce Richardson } 1466c1d14583SBruce Richardson 1467c1d14583SBruce Richardson #define ICE_DCF_32_BIT_WIDTH (CHAR_BIT * 4) 1468c1d14583SBruce Richardson #define ICE_DCF_48_BIT_WIDTH (CHAR_BIT * 6) 1469c1d14583SBruce Richardson #define ICE_DCF_48_BIT_MASK RTE_LEN2MASK(ICE_DCF_48_BIT_WIDTH, uint64_t) 1470c1d14583SBruce Richardson 1471c1d14583SBruce Richardson static void 1472c1d14583SBruce Richardson ice_dcf_stat_update_48(uint64_t *offset, uint64_t *stat) 1473c1d14583SBruce Richardson { 1474c1d14583SBruce Richardson if (*stat >= *offset) 1475c1d14583SBruce Richardson *stat = *stat - *offset; 1476c1d14583SBruce Richardson else 1477c1d14583SBruce Richardson *stat = (uint64_t)((*stat + 1478c1d14583SBruce Richardson ((uint64_t)1 << ICE_DCF_48_BIT_WIDTH)) - *offset); 1479c1d14583SBruce Richardson 1480c1d14583SBruce Richardson *stat &= ICE_DCF_48_BIT_MASK; 1481c1d14583SBruce Richardson } 1482c1d14583SBruce Richardson 1483c1d14583SBruce Richardson static void 1484c1d14583SBruce Richardson ice_dcf_stat_update_32(uint64_t *offset, uint64_t *stat) 1485c1d14583SBruce Richardson { 1486c1d14583SBruce Richardson if (*stat >= *offset) 1487c1d14583SBruce Richardson *stat = (uint64_t)(*stat - *offset); 1488c1d14583SBruce Richardson else 1489c1d14583SBruce Richardson *stat = (uint64_t)((*stat + 1490c1d14583SBruce Richardson ((uint64_t)1 << ICE_DCF_32_BIT_WIDTH)) - *offset); 1491c1d14583SBruce Richardson } 1492c1d14583SBruce Richardson 1493c1d14583SBruce Richardson static void 1494c1d14583SBruce Richardson ice_dcf_update_stats(struct virtchnl_eth_stats *oes, 1495c1d14583SBruce Richardson struct virtchnl_eth_stats *nes) 1496c1d14583SBruce Richardson { 1497c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->rx_bytes, &nes->rx_bytes); 1498c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->rx_unicast, &nes->rx_unicast); 1499c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->rx_multicast, &nes->rx_multicast); 1500c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->rx_broadcast, &nes->rx_broadcast); 1501c1d14583SBruce Richardson ice_dcf_stat_update_32(&oes->rx_discards, &nes->rx_discards); 1502c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->tx_bytes, &nes->tx_bytes); 1503c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->tx_unicast, &nes->tx_unicast); 1504c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->tx_multicast, &nes->tx_multicast); 1505c1d14583SBruce Richardson ice_dcf_stat_update_48(&oes->tx_broadcast, &nes->tx_broadcast); 1506c1d14583SBruce Richardson ice_dcf_stat_update_32(&oes->tx_errors, &nes->tx_errors); 1507c1d14583SBruce Richardson ice_dcf_stat_update_32(&oes->tx_discards, &nes->tx_discards); 1508c1d14583SBruce Richardson } 1509c1d14583SBruce Richardson 1510c1d14583SBruce Richardson 1511c1d14583SBruce Richardson static int 1512c1d14583SBruce Richardson ice_dcf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 1513c1d14583SBruce Richardson { 1514c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 1515c1d14583SBruce Richardson struct ice_dcf_hw *hw = &ad->real_hw; 1516c1d14583SBruce Richardson struct virtchnl_eth_stats pstats; 1517c1d14583SBruce Richardson int ret; 1518c1d14583SBruce Richardson 1519c1d14583SBruce Richardson if (hw->resetting) { 1520c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 1521c1d14583SBruce Richardson "The DCF has been reset by PF, please reinit first"); 1522c1d14583SBruce Richardson return -EIO; 1523c1d14583SBruce Richardson } 1524c1d14583SBruce Richardson 1525c1d14583SBruce Richardson ret = ice_dcf_query_stats(hw, &pstats); 1526c1d14583SBruce Richardson if (ret == 0) { 1527c1d14583SBruce Richardson ice_dcf_update_stats(&hw->eth_stats_offset, &pstats); 1528c1d14583SBruce Richardson stats->ipackets = pstats.rx_unicast + pstats.rx_multicast + 1529c1d14583SBruce Richardson pstats.rx_broadcast - pstats.rx_discards; 1530c1d14583SBruce Richardson stats->opackets = pstats.tx_broadcast + pstats.tx_multicast + 1531c1d14583SBruce Richardson pstats.tx_unicast; 1532c1d14583SBruce Richardson stats->imissed = pstats.rx_discards; 1533c1d14583SBruce Richardson stats->oerrors = pstats.tx_errors + pstats.tx_discards; 1534c1d14583SBruce Richardson stats->ibytes = pstats.rx_bytes; 1535c1d14583SBruce Richardson stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN; 1536c1d14583SBruce Richardson stats->obytes = pstats.tx_bytes; 1537c1d14583SBruce Richardson } else { 1538c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Get statistics failed"); 1539c1d14583SBruce Richardson } 1540c1d14583SBruce Richardson return ret; 1541c1d14583SBruce Richardson } 1542c1d14583SBruce Richardson 1543c1d14583SBruce Richardson static int 1544c1d14583SBruce Richardson ice_dcf_stats_reset(struct rte_eth_dev *dev) 1545c1d14583SBruce Richardson { 1546c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 1547c1d14583SBruce Richardson struct ice_dcf_hw *hw = &ad->real_hw; 1548c1d14583SBruce Richardson struct virtchnl_eth_stats pstats; 1549c1d14583SBruce Richardson int ret; 1550c1d14583SBruce Richardson 1551c1d14583SBruce Richardson if (hw->resetting) 1552c1d14583SBruce Richardson return 0; 1553c1d14583SBruce Richardson 1554c1d14583SBruce Richardson /* read stat values to clear hardware registers */ 1555c1d14583SBruce Richardson ret = ice_dcf_query_stats(hw, &pstats); 1556c1d14583SBruce Richardson if (ret != 0) 1557c1d14583SBruce Richardson return ret; 1558c1d14583SBruce Richardson 1559c1d14583SBruce Richardson /* set stats offset base on current values */ 1560c1d14583SBruce Richardson hw->eth_stats_offset = pstats; 1561c1d14583SBruce Richardson 1562c1d14583SBruce Richardson return 0; 1563c1d14583SBruce Richardson } 1564c1d14583SBruce Richardson 1565c1d14583SBruce Richardson static int ice_dcf_xstats_get_names(__rte_unused struct rte_eth_dev *dev, 1566c1d14583SBruce Richardson struct rte_eth_xstat_name *xstats_names, 1567c1d14583SBruce Richardson __rte_unused unsigned int limit) 1568c1d14583SBruce Richardson { 1569c1d14583SBruce Richardson unsigned int i; 1570c1d14583SBruce Richardson 1571c1d14583SBruce Richardson if (xstats_names != NULL) 1572c1d14583SBruce Richardson for (i = 0; i < ICE_DCF_NB_XSTATS; i++) { 1573c1d14583SBruce Richardson snprintf(xstats_names[i].name, 1574c1d14583SBruce Richardson sizeof(xstats_names[i].name), 1575c1d14583SBruce Richardson "%s", rte_ice_dcf_stats_strings[i].name); 1576c1d14583SBruce Richardson } 1577c1d14583SBruce Richardson return ICE_DCF_NB_XSTATS; 1578c1d14583SBruce Richardson } 1579c1d14583SBruce Richardson 1580c1d14583SBruce Richardson static int ice_dcf_xstats_get(struct rte_eth_dev *dev, 1581c1d14583SBruce Richardson struct rte_eth_xstat *xstats, unsigned int n) 1582c1d14583SBruce Richardson { 1583c1d14583SBruce Richardson int ret; 1584c1d14583SBruce Richardson unsigned int i; 1585c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = 1586c1d14583SBruce Richardson ICE_DCF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); 1587c1d14583SBruce Richardson struct ice_dcf_hw *hw = &adapter->real_hw; 1588c1d14583SBruce Richardson struct virtchnl_eth_stats *postats = &hw->eth_stats_offset; 1589c1d14583SBruce Richardson struct virtchnl_eth_stats pnstats; 1590c1d14583SBruce Richardson 1591c1d14583SBruce Richardson if (n < ICE_DCF_NB_XSTATS) 1592c1d14583SBruce Richardson return ICE_DCF_NB_XSTATS; 1593c1d14583SBruce Richardson 1594c1d14583SBruce Richardson ret = ice_dcf_query_stats(hw, &pnstats); 1595c1d14583SBruce Richardson if (ret != 0) 1596c1d14583SBruce Richardson return 0; 1597c1d14583SBruce Richardson 1598c1d14583SBruce Richardson if (!xstats) 1599c1d14583SBruce Richardson return 0; 1600c1d14583SBruce Richardson 1601c1d14583SBruce Richardson ice_dcf_update_stats(postats, &pnstats); 1602c1d14583SBruce Richardson 1603c1d14583SBruce Richardson /* loop over xstats array and values from pstats */ 1604c1d14583SBruce Richardson for (i = 0; i < ICE_DCF_NB_XSTATS; i++) { 1605c1d14583SBruce Richardson xstats[i].id = i; 1606c1d14583SBruce Richardson xstats[i].value = *(uint64_t *)(((char *)&pnstats) + 1607c1d14583SBruce Richardson rte_ice_dcf_stats_strings[i].offset); 1608c1d14583SBruce Richardson } 1609c1d14583SBruce Richardson 1610c1d14583SBruce Richardson return ICE_DCF_NB_XSTATS; 1611c1d14583SBruce Richardson } 1612c1d14583SBruce Richardson 1613c1d14583SBruce Richardson static void 1614c1d14583SBruce Richardson ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter) 1615c1d14583SBruce Richardson { 1616c1d14583SBruce Richardson if (dcf_adapter->repr_infos) { 1617c1d14583SBruce Richardson rte_free(dcf_adapter->repr_infos); 1618c1d14583SBruce Richardson dcf_adapter->repr_infos = NULL; 1619c1d14583SBruce Richardson } 1620c1d14583SBruce Richardson } 1621c1d14583SBruce Richardson 1622c1d14583SBruce Richardson int 1623c1d14583SBruce Richardson ice_dcf_handle_vf_repr_close(struct ice_dcf_adapter *dcf_adapter, 1624c1d14583SBruce Richardson uint16_t vf_id) 1625c1d14583SBruce Richardson { 1626c1d14583SBruce Richardson struct ice_dcf_repr_info *vf_rep_info; 1627c1d14583SBruce Richardson 1628c1d14583SBruce Richardson if (dcf_adapter->num_reprs >= vf_id) { 1629c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Invalid VF id: %d", vf_id); 1630c1d14583SBruce Richardson return -1; 1631c1d14583SBruce Richardson } 1632c1d14583SBruce Richardson 1633c1d14583SBruce Richardson if (!dcf_adapter->repr_infos) 1634c1d14583SBruce Richardson return 0; 1635c1d14583SBruce Richardson 1636c1d14583SBruce Richardson vf_rep_info = &dcf_adapter->repr_infos[vf_id]; 1637c1d14583SBruce Richardson vf_rep_info->vf_rep_eth_dev = NULL; 1638c1d14583SBruce Richardson 1639c1d14583SBruce Richardson return 0; 1640c1d14583SBruce Richardson } 1641c1d14583SBruce Richardson 1642c1d14583SBruce Richardson static int 1643c1d14583SBruce Richardson ice_dcf_init_repr_info(struct ice_dcf_adapter *dcf_adapter) 1644c1d14583SBruce Richardson { 1645c1d14583SBruce Richardson dcf_adapter->repr_infos = 1646c1d14583SBruce Richardson rte_calloc("ice_dcf_rep_info", 1647c1d14583SBruce Richardson dcf_adapter->real_hw.num_vfs, 1648c1d14583SBruce Richardson sizeof(dcf_adapter->repr_infos[0]), 0); 1649c1d14583SBruce Richardson if (!dcf_adapter->repr_infos) { 1650c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Failed to alloc memory for VF representors"); 1651c1d14583SBruce Richardson return -ENOMEM; 1652c1d14583SBruce Richardson } 1653c1d14583SBruce Richardson 1654c1d14583SBruce Richardson return 0; 1655c1d14583SBruce Richardson } 1656c1d14583SBruce Richardson 1657c1d14583SBruce Richardson static int 1658c1d14583SBruce Richardson ice_dcf_dev_close(struct rte_eth_dev *dev) 1659c1d14583SBruce Richardson { 1660c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1661c1d14583SBruce Richardson 1662c1d14583SBruce Richardson if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1663c1d14583SBruce Richardson return 0; 1664c1d14583SBruce Richardson 1665c1d14583SBruce Richardson ice_dcf_vf_repr_notify_all(adapter, false); 1666c1d14583SBruce Richardson (void)ice_dcf_dev_stop(dev); 1667c1d14583SBruce Richardson 1668c1d14583SBruce Richardson ice_free_queues(dev); 1669c1d14583SBruce Richardson ice_dcf_uninit_parent_adapter(dev); 1670c1d14583SBruce Richardson ice_dcf_uninit_hw(dev, &adapter->real_hw); 1671c1d14583SBruce Richardson 1672c1d14583SBruce Richardson return 0; 1673c1d14583SBruce Richardson } 1674c1d14583SBruce Richardson 1675c1d14583SBruce Richardson int 1676c1d14583SBruce Richardson ice_dcf_link_update(struct rte_eth_dev *dev, 1677c1d14583SBruce Richardson __rte_unused int wait_to_complete) 1678c1d14583SBruce Richardson { 1679c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 1680c1d14583SBruce Richardson struct ice_dcf_hw *hw = &ad->real_hw; 1681c1d14583SBruce Richardson struct rte_eth_link new_link; 1682c1d14583SBruce Richardson 1683c1d14583SBruce Richardson memset(&new_link, 0, sizeof(new_link)); 1684c1d14583SBruce Richardson 1685c1d14583SBruce Richardson /* Only read status info stored in VF, and the info is updated 1686c1d14583SBruce Richardson * when receive LINK_CHANGE event from PF by virtchnl. 1687c1d14583SBruce Richardson */ 1688c1d14583SBruce Richardson switch (hw->link_speed) { 1689c1d14583SBruce Richardson case 10: 1690c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_10M; 1691c1d14583SBruce Richardson break; 1692c1d14583SBruce Richardson case 100: 1693c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_100M; 1694c1d14583SBruce Richardson break; 1695c1d14583SBruce Richardson case 1000: 1696c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_1G; 1697c1d14583SBruce Richardson break; 1698c1d14583SBruce Richardson case 10000: 1699c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_10G; 1700c1d14583SBruce Richardson break; 1701c1d14583SBruce Richardson case 20000: 1702c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_20G; 1703c1d14583SBruce Richardson break; 1704c1d14583SBruce Richardson case 25000: 1705c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_25G; 1706c1d14583SBruce Richardson break; 1707c1d14583SBruce Richardson case 40000: 1708c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_40G; 1709c1d14583SBruce Richardson break; 1710c1d14583SBruce Richardson case 50000: 1711c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_50G; 1712c1d14583SBruce Richardson break; 1713c1d14583SBruce Richardson case 100000: 1714c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_100G; 1715c1d14583SBruce Richardson break; 1716c1d14583SBruce Richardson default: 1717c1d14583SBruce Richardson new_link.link_speed = RTE_ETH_SPEED_NUM_NONE; 1718c1d14583SBruce Richardson break; 1719c1d14583SBruce Richardson } 1720c1d14583SBruce Richardson 1721c1d14583SBruce Richardson new_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX; 1722c1d14583SBruce Richardson new_link.link_status = hw->link_up ? RTE_ETH_LINK_UP : 1723c1d14583SBruce Richardson RTE_ETH_LINK_DOWN; 1724c1d14583SBruce Richardson new_link.link_autoneg = !(dev->data->dev_conf.link_speeds & 1725c1d14583SBruce Richardson RTE_ETH_LINK_SPEED_FIXED); 1726c1d14583SBruce Richardson 1727c1d14583SBruce Richardson return rte_eth_linkstatus_set(dev, &new_link); 1728c1d14583SBruce Richardson } 1729c1d14583SBruce Richardson 1730c1d14583SBruce Richardson static int 1731c1d14583SBruce Richardson ice_dcf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu __rte_unused) 1732c1d14583SBruce Richardson { 1733c1d14583SBruce Richardson /* mtu setting is forbidden if port is start */ 1734c1d14583SBruce Richardson if (dev->data->dev_started != 0) { 1735c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "port %d must be stopped before configuration", 1736c1d14583SBruce Richardson dev->data->port_id); 1737c1d14583SBruce Richardson return -EBUSY; 1738c1d14583SBruce Richardson } 1739c1d14583SBruce Richardson 1740c1d14583SBruce Richardson return 0; 1741c1d14583SBruce Richardson } 1742c1d14583SBruce Richardson 1743c1d14583SBruce Richardson bool 1744c1d14583SBruce Richardson ice_dcf_adminq_need_retry(struct ice_adapter *ad) 1745c1d14583SBruce Richardson { 1746c1d14583SBruce Richardson return ad->hw.dcf_enabled && 1747c1d14583SBruce Richardson !rte_atomic_load_explicit(&ad->dcf_state_on, rte_memory_order_relaxed); 1748c1d14583SBruce Richardson } 1749c1d14583SBruce Richardson 1750c1d14583SBruce Richardson /* Add UDP tunneling port */ 1751c1d14583SBruce Richardson static int 1752c1d14583SBruce Richardson ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, 1753c1d14583SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 1754c1d14583SBruce Richardson { 1755c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1756c1d14583SBruce Richardson struct ice_adapter *parent_adapter = &adapter->parent; 1757c1d14583SBruce Richardson struct ice_hw *parent_hw = &parent_adapter->hw; 1758c1d14583SBruce Richardson int ret = 0; 1759c1d14583SBruce Richardson 1760c1d14583SBruce Richardson if (!udp_tunnel) 1761c1d14583SBruce Richardson return -EINVAL; 1762c1d14583SBruce Richardson 1763c1d14583SBruce Richardson switch (udp_tunnel->prot_type) { 1764c1d14583SBruce Richardson case RTE_ETH_TUNNEL_TYPE_VXLAN: 1765c1d14583SBruce Richardson ret = ice_create_tunnel(parent_hw, TNL_VXLAN, 1766c1d14583SBruce Richardson udp_tunnel->udp_port); 1767c1d14583SBruce Richardson break; 1768c1d14583SBruce Richardson case RTE_ETH_TUNNEL_TYPE_ECPRI: 1769c1d14583SBruce Richardson ret = ice_create_tunnel(parent_hw, TNL_ECPRI, 1770c1d14583SBruce Richardson udp_tunnel->udp_port); 1771c1d14583SBruce Richardson break; 1772c1d14583SBruce Richardson default: 1773c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Invalid tunnel type"); 1774c1d14583SBruce Richardson ret = -EINVAL; 1775c1d14583SBruce Richardson break; 1776c1d14583SBruce Richardson } 1777c1d14583SBruce Richardson 1778c1d14583SBruce Richardson return ret; 1779c1d14583SBruce Richardson } 1780c1d14583SBruce Richardson 1781c1d14583SBruce Richardson /* Delete UDP tunneling port */ 1782c1d14583SBruce Richardson static int 1783c1d14583SBruce Richardson ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, 1784c1d14583SBruce Richardson struct rte_eth_udp_tunnel *udp_tunnel) 1785c1d14583SBruce Richardson { 1786c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = dev->data->dev_private; 1787c1d14583SBruce Richardson struct ice_adapter *parent_adapter = &adapter->parent; 1788c1d14583SBruce Richardson struct ice_hw *parent_hw = &parent_adapter->hw; 1789c1d14583SBruce Richardson int ret = 0; 1790c1d14583SBruce Richardson 1791c1d14583SBruce Richardson if (!udp_tunnel) 1792c1d14583SBruce Richardson return -EINVAL; 1793c1d14583SBruce Richardson 1794c1d14583SBruce Richardson switch (udp_tunnel->prot_type) { 1795c1d14583SBruce Richardson case RTE_ETH_TUNNEL_TYPE_VXLAN: 1796c1d14583SBruce Richardson case RTE_ETH_TUNNEL_TYPE_ECPRI: 1797c1d14583SBruce Richardson ret = ice_destroy_tunnel(parent_hw, udp_tunnel->udp_port, 0); 1798c1d14583SBruce Richardson break; 1799c1d14583SBruce Richardson default: 1800c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "Invalid tunnel type"); 1801c1d14583SBruce Richardson ret = -EINVAL; 1802c1d14583SBruce Richardson break; 1803c1d14583SBruce Richardson } 1804c1d14583SBruce Richardson 1805c1d14583SBruce Richardson return ret; 1806c1d14583SBruce Richardson } 1807c1d14583SBruce Richardson 1808c1d14583SBruce Richardson static int 1809c1d14583SBruce Richardson ice_dcf_tm_ops_get(struct rte_eth_dev *dev __rte_unused, 1810c1d14583SBruce Richardson void *arg) 1811c1d14583SBruce Richardson { 1812c1d14583SBruce Richardson if (!arg) 1813c1d14583SBruce Richardson return -EINVAL; 1814c1d14583SBruce Richardson 1815c1d14583SBruce Richardson *(const void **)arg = &ice_dcf_tm_ops; 1816c1d14583SBruce Richardson 1817c1d14583SBruce Richardson return 0; 1818c1d14583SBruce Richardson } 1819c1d14583SBruce Richardson 1820c1d14583SBruce Richardson static inline void 1821c1d14583SBruce Richardson ice_dcf_reset_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw) 1822c1d14583SBruce Richardson { 1823c1d14583SBruce Richardson ice_dcf_uninit_hw(eth_dev, hw); 1824c1d14583SBruce Richardson ice_dcf_init_hw(eth_dev, hw); 1825c1d14583SBruce Richardson } 1826c1d14583SBruce Richardson 1827c1d14583SBruce Richardson /* Check if reset has been triggered by PF */ 1828c1d14583SBruce Richardson static inline bool 1829c1d14583SBruce Richardson ice_dcf_is_reset(struct rte_eth_dev *dev) 1830c1d14583SBruce Richardson { 1831c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 1832c1d14583SBruce Richardson struct iavf_hw *hw = &ad->real_hw.avf; 1833c1d14583SBruce Richardson 1834c1d14583SBruce Richardson return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) & 1835c1d14583SBruce Richardson IAVF_VF_ARQLEN1_ARQENABLE_MASK); 1836c1d14583SBruce Richardson } 1837c1d14583SBruce Richardson 1838c1d14583SBruce Richardson static int 1839c1d14583SBruce Richardson ice_dcf_dev_reset(struct rte_eth_dev *dev) 1840c1d14583SBruce Richardson { 1841c1d14583SBruce Richardson struct ice_dcf_adapter *ad = dev->data->dev_private; 1842c1d14583SBruce Richardson struct ice_dcf_hw *hw = &ad->real_hw; 1843c1d14583SBruce Richardson int ret; 1844c1d14583SBruce Richardson 1845c1d14583SBruce Richardson if (ice_dcf_is_reset(dev)) { 1846c1d14583SBruce Richardson if (!ad->real_hw.resetting) 1847c1d14583SBruce Richardson ad->real_hw.resetting = true; 1848c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "The DCF has been reset by PF"); 1849c1d14583SBruce Richardson 1850c1d14583SBruce Richardson /* 1851c1d14583SBruce Richardson * Simply reset hw to trigger an additional DCF enable/disable 1852c1d14583SBruce Richardson * cycle which help to workaround the issue that kernel driver 1853c1d14583SBruce Richardson * may not clean up resource during previous reset. 1854c1d14583SBruce Richardson */ 1855c1d14583SBruce Richardson ice_dcf_reset_hw(dev, hw); 1856c1d14583SBruce Richardson } 1857c1d14583SBruce Richardson 1858c1d14583SBruce Richardson ret = ice_dcf_dev_close(dev); 1859c1d14583SBruce Richardson if (ret) 1860c1d14583SBruce Richardson return ret; 1861c1d14583SBruce Richardson 1862c1d14583SBruce Richardson ret = ice_dcf_dev_init(dev); 1863c1d14583SBruce Richardson 1864c1d14583SBruce Richardson return ret; 1865c1d14583SBruce Richardson } 1866c1d14583SBruce Richardson 1867c1d14583SBruce Richardson static const uint32_t * 1868c1d14583SBruce Richardson ice_dcf_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused, 1869c1d14583SBruce Richardson size_t *no_of_elements) 1870c1d14583SBruce Richardson { 1871c1d14583SBruce Richardson static const uint32_t ptypes[] = { 1872c1d14583SBruce Richardson RTE_PTYPE_L2_ETHER, 1873c1d14583SBruce Richardson RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, 1874c1d14583SBruce Richardson RTE_PTYPE_L4_FRAG, 1875c1d14583SBruce Richardson RTE_PTYPE_L4_ICMP, 1876c1d14583SBruce Richardson RTE_PTYPE_L4_NONFRAG, 1877c1d14583SBruce Richardson RTE_PTYPE_L4_SCTP, 1878c1d14583SBruce Richardson RTE_PTYPE_L4_TCP, 1879c1d14583SBruce Richardson RTE_PTYPE_L4_UDP, 1880c1d14583SBruce Richardson }; 1881c1d14583SBruce Richardson *no_of_elements = RTE_DIM(ptypes); 1882c1d14583SBruce Richardson return ptypes; 1883c1d14583SBruce Richardson } 1884c1d14583SBruce Richardson 1885c1d14583SBruce Richardson static const struct eth_dev_ops ice_dcf_eth_dev_ops = { 1886c1d14583SBruce Richardson .dev_start = ice_dcf_dev_start, 1887c1d14583SBruce Richardson .dev_stop = ice_dcf_dev_stop, 1888c1d14583SBruce Richardson .dev_close = ice_dcf_dev_close, 1889c1d14583SBruce Richardson .dev_reset = ice_dcf_dev_reset, 1890c1d14583SBruce Richardson .dev_configure = ice_dcf_dev_configure, 1891c1d14583SBruce Richardson .dev_infos_get = ice_dcf_dev_info_get, 1892c1d14583SBruce Richardson .dev_supported_ptypes_get = ice_dcf_dev_supported_ptypes_get, 1893c1d14583SBruce Richardson .rx_queue_setup = ice_rx_queue_setup, 1894c1d14583SBruce Richardson .tx_queue_setup = ice_tx_queue_setup, 1895c1d14583SBruce Richardson .rx_queue_release = ice_dev_rx_queue_release, 1896c1d14583SBruce Richardson .tx_queue_release = ice_dev_tx_queue_release, 1897c1d14583SBruce Richardson .rx_queue_start = ice_dcf_rx_queue_start, 1898c1d14583SBruce Richardson .tx_queue_start = ice_dcf_tx_queue_start, 1899c1d14583SBruce Richardson .rx_queue_stop = ice_dcf_rx_queue_stop, 1900c1d14583SBruce Richardson .tx_queue_stop = ice_dcf_tx_queue_stop, 1901c1d14583SBruce Richardson .rxq_info_get = ice_rxq_info_get, 1902c1d14583SBruce Richardson .txq_info_get = ice_txq_info_get, 1903c1d14583SBruce Richardson .get_monitor_addr = ice_get_monitor_addr, 1904c1d14583SBruce Richardson .link_update = ice_dcf_link_update, 1905c1d14583SBruce Richardson .stats_get = ice_dcf_stats_get, 1906c1d14583SBruce Richardson .stats_reset = ice_dcf_stats_reset, 1907c1d14583SBruce Richardson .xstats_get = ice_dcf_xstats_get, 1908c1d14583SBruce Richardson .xstats_get_names = ice_dcf_xstats_get_names, 1909c1d14583SBruce Richardson .xstats_reset = ice_dcf_stats_reset, 1910c1d14583SBruce Richardson .promiscuous_enable = ice_dcf_dev_promiscuous_enable, 1911c1d14583SBruce Richardson .promiscuous_disable = ice_dcf_dev_promiscuous_disable, 1912c1d14583SBruce Richardson .allmulticast_enable = ice_dcf_dev_allmulticast_enable, 1913c1d14583SBruce Richardson .allmulticast_disable = ice_dcf_dev_allmulticast_disable, 1914c1d14583SBruce Richardson .mac_addr_add = dcf_dev_add_mac_addr, 1915c1d14583SBruce Richardson .mac_addr_remove = dcf_dev_del_mac_addr, 1916c1d14583SBruce Richardson .set_mc_addr_list = dcf_set_mc_addr_list, 1917c1d14583SBruce Richardson .mac_addr_set = dcf_dev_set_default_mac_addr, 1918c1d14583SBruce Richardson .vlan_filter_set = dcf_dev_vlan_filter_set, 1919c1d14583SBruce Richardson .vlan_offload_set = dcf_dev_vlan_offload_set, 1920c1d14583SBruce Richardson .flow_ops_get = ice_dcf_dev_flow_ops_get, 1921c1d14583SBruce Richardson .udp_tunnel_port_add = ice_dcf_dev_udp_tunnel_port_add, 1922c1d14583SBruce Richardson .udp_tunnel_port_del = ice_dcf_dev_udp_tunnel_port_del, 1923c1d14583SBruce Richardson .tm_ops_get = ice_dcf_tm_ops_get, 1924c1d14583SBruce Richardson .reta_update = ice_dcf_dev_rss_reta_update, 1925c1d14583SBruce Richardson .reta_query = ice_dcf_dev_rss_reta_query, 1926c1d14583SBruce Richardson .rss_hash_update = ice_dcf_dev_rss_hash_update, 1927c1d14583SBruce Richardson .rss_hash_conf_get = ice_dcf_dev_rss_hash_conf_get, 1928c1d14583SBruce Richardson .tx_done_cleanup = ice_tx_done_cleanup, 1929c1d14583SBruce Richardson .mtu_set = ice_dcf_dev_mtu_set, 1930c1d14583SBruce Richardson }; 1931c1d14583SBruce Richardson 1932c1d14583SBruce Richardson static int 1933c1d14583SBruce Richardson ice_dcf_dev_init(struct rte_eth_dev *eth_dev) 1934c1d14583SBruce Richardson { 1935c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = eth_dev->data->dev_private; 1936c1d14583SBruce Richardson struct ice_adapter *parent_adapter = &adapter->parent; 1937c1d14583SBruce Richardson 1938c1d14583SBruce Richardson eth_dev->dev_ops = &ice_dcf_eth_dev_ops; 1939c1d14583SBruce Richardson eth_dev->rx_pkt_burst = ice_dcf_recv_pkts; 1940c1d14583SBruce Richardson eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts; 1941c1d14583SBruce Richardson 1942c1d14583SBruce Richardson if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1943c1d14583SBruce Richardson return 0; 1944c1d14583SBruce Richardson 1945c1d14583SBruce Richardson adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg; 1946c1d14583SBruce Richardson if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) { 1947c1d14583SBruce Richardson PMD_INIT_LOG(ERR, "Failed to init DCF hardware"); 1948c1d14583SBruce Richardson rte_atomic_store_explicit(&parent_adapter->dcf_state_on, false, 1949c1d14583SBruce Richardson rte_memory_order_relaxed); 1950c1d14583SBruce Richardson return -1; 1951c1d14583SBruce Richardson } 1952c1d14583SBruce Richardson 1953c1d14583SBruce Richardson rte_atomic_store_explicit(&parent_adapter->dcf_state_on, true, rte_memory_order_relaxed); 1954c1d14583SBruce Richardson 1955c1d14583SBruce Richardson if (ice_dcf_init_parent_adapter(eth_dev) != 0) { 1956c1d14583SBruce Richardson PMD_INIT_LOG(ERR, "Failed to init DCF parent adapter"); 1957c1d14583SBruce Richardson ice_dcf_uninit_hw(eth_dev, &adapter->real_hw); 1958c1d14583SBruce Richardson return -1; 1959c1d14583SBruce Richardson } 1960c1d14583SBruce Richardson 1961c1d14583SBruce Richardson ice_dcf_stats_reset(eth_dev); 1962c1d14583SBruce Richardson 1963c1d14583SBruce Richardson dcf_config_promisc(adapter, false, false); 1964c1d14583SBruce Richardson ice_dcf_vf_repr_notify_all(adapter, true); 1965c1d14583SBruce Richardson 1966c1d14583SBruce Richardson return 0; 1967c1d14583SBruce Richardson } 1968c1d14583SBruce Richardson 1969c1d14583SBruce Richardson static int 1970c1d14583SBruce Richardson ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev) 1971c1d14583SBruce Richardson { 1972c1d14583SBruce Richardson struct ice_dcf_adapter *adapter = eth_dev->data->dev_private; 1973c1d14583SBruce Richardson 1974c1d14583SBruce Richardson ice_dcf_free_repr_info(adapter); 1975c1d14583SBruce Richardson ice_dcf_dev_close(eth_dev); 1976c1d14583SBruce Richardson 1977c1d14583SBruce Richardson return 0; 1978c1d14583SBruce Richardson } 1979c1d14583SBruce Richardson 1980c1d14583SBruce Richardson static int 1981c1d14583SBruce Richardson ice_dcf_engine_disabled_handler(__rte_unused const char *key, 1982c1d14583SBruce Richardson const char *value, __rte_unused void *opaque) 1983c1d14583SBruce Richardson { 1984c1d14583SBruce Richardson if (strcmp(value, "off")) 1985c1d14583SBruce Richardson return -1; 1986c1d14583SBruce Richardson 1987c1d14583SBruce Richardson return 0; 1988c1d14583SBruce Richardson } 1989c1d14583SBruce Richardson 1990c1d14583SBruce Richardson static int 1991c1d14583SBruce Richardson ice_dcf_cap_check_handler(__rte_unused const char *key, 1992c1d14583SBruce Richardson const char *value, __rte_unused void *opaque) 1993c1d14583SBruce Richardson { 1994c1d14583SBruce Richardson if (strcmp(value, "dcf")) 1995c1d14583SBruce Richardson return -1; 1996c1d14583SBruce Richardson 1997c1d14583SBruce Richardson return 0; 1998c1d14583SBruce Richardson } 1999c1d14583SBruce Richardson 2000c1d14583SBruce Richardson int 2001c1d14583SBruce Richardson ice_devargs_check(struct rte_devargs *devargs, enum ice_dcf_devrarg devarg_type) 2002c1d14583SBruce Richardson { 2003c1d14583SBruce Richardson struct rte_kvargs *kvlist; 2004c1d14583SBruce Richardson unsigned int i = 0; 2005c1d14583SBruce Richardson int ret = 0; 2006c1d14583SBruce Richardson 2007c1d14583SBruce Richardson if (devargs == NULL) 2008c1d14583SBruce Richardson return 0; 2009c1d14583SBruce Richardson 2010c1d14583SBruce Richardson kvlist = rte_kvargs_parse(devargs->args, NULL); 2011c1d14583SBruce Richardson if (kvlist == NULL) 2012c1d14583SBruce Richardson return 0; 2013c1d14583SBruce Richardson 2014c1d14583SBruce Richardson for (i = 0; i < ARRAY_SIZE(ice_devargs_table); i++) { 2015c1d14583SBruce Richardson if (devarg_type == ice_devargs_table[i].type) { 2016c1d14583SBruce Richardson if (!rte_kvargs_count(kvlist, ice_devargs_table[i].key)) 2017c1d14583SBruce Richardson goto exit; 2018c1d14583SBruce Richardson 2019c1d14583SBruce Richardson if (rte_kvargs_process(kvlist, ice_devargs_table[i].key, 2020c1d14583SBruce Richardson ice_devargs_table[i].handler, NULL) < 0) 2021c1d14583SBruce Richardson goto exit; 2022c1d14583SBruce Richardson ret = 1; 2023c1d14583SBruce Richardson break; 2024c1d14583SBruce Richardson } 2025c1d14583SBruce Richardson } 2026c1d14583SBruce Richardson exit: 2027c1d14583SBruce Richardson rte_kvargs_free(kvlist); 2028c1d14583SBruce Richardson return ret; 2029c1d14583SBruce Richardson } 2030c1d14583SBruce Richardson 2031c1d14583SBruce Richardson static int 2032c1d14583SBruce Richardson eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv, 2033c1d14583SBruce Richardson struct rte_pci_device *pci_dev) 2034c1d14583SBruce Richardson { 2035c1d14583SBruce Richardson struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 }; 2036c1d14583SBruce Richardson struct ice_dcf_vf_repr_param repr_param; 2037c1d14583SBruce Richardson char repr_name[RTE_ETH_NAME_MAX_LEN]; 2038c1d14583SBruce Richardson struct ice_dcf_adapter *dcf_adapter; 2039c1d14583SBruce Richardson struct rte_eth_dev *dcf_ethdev; 2040c1d14583SBruce Richardson uint16_t dcf_vsi_id; 2041c1d14583SBruce Richardson int i, ret; 2042c1d14583SBruce Richardson 2043c1d14583SBruce Richardson if (!ice_devargs_check(pci_dev->device.devargs, ICE_DCF_DEVARG_CAP)) 2044c1d14583SBruce Richardson return 1; 2045c1d14583SBruce Richardson 2046c1d14583SBruce Richardson ret = rte_eth_devargs_parse(pci_dev->device.devargs->args, ð_da, 1); 2047c1d14583SBruce Richardson if (ret < 0) 2048c1d14583SBruce Richardson return ret; 2049c1d14583SBruce Richardson 2050c1d14583SBruce Richardson ret = rte_eth_dev_pci_generic_probe(pci_dev, 2051c1d14583SBruce Richardson sizeof(struct ice_dcf_adapter), 2052c1d14583SBruce Richardson ice_dcf_dev_init); 2053c1d14583SBruce Richardson if (ret || !eth_da.nb_representor_ports) 2054c1d14583SBruce Richardson return ret; 2055c1d14583SBruce Richardson if (eth_da.type != RTE_ETH_REPRESENTOR_VF) 2056c1d14583SBruce Richardson return -ENOTSUP; 2057c1d14583SBruce Richardson 2058c1d14583SBruce Richardson dcf_ethdev = rte_eth_dev_allocated(pci_dev->device.name); 2059c1d14583SBruce Richardson if (dcf_ethdev == NULL) 2060c1d14583SBruce Richardson return -ENODEV; 2061c1d14583SBruce Richardson 2062c1d14583SBruce Richardson dcf_adapter = dcf_ethdev->data->dev_private; 2063c1d14583SBruce Richardson ret = ice_dcf_init_repr_info(dcf_adapter); 2064c1d14583SBruce Richardson if (ret) 2065c1d14583SBruce Richardson return ret; 2066c1d14583SBruce Richardson 2067c1d14583SBruce Richardson if (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs || 2068c1d14583SBruce Richardson eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) { 2069c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "the number of port representors is too large: %u", 2070c1d14583SBruce Richardson eth_da.nb_representor_ports); 2071c1d14583SBruce Richardson ice_dcf_free_repr_info(dcf_adapter); 2072c1d14583SBruce Richardson return -EINVAL; 2073c1d14583SBruce Richardson } 2074c1d14583SBruce Richardson 2075c1d14583SBruce Richardson dcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID; 2076c1d14583SBruce Richardson 2077c1d14583SBruce Richardson repr_param.dcf_eth_dev = dcf_ethdev; 2078c1d14583SBruce Richardson repr_param.switch_domain_id = 0; 2079c1d14583SBruce Richardson 2080c1d14583SBruce Richardson for (i = 0; i < eth_da.nb_representor_ports; i++) { 2081c1d14583SBruce Richardson uint16_t vf_id = eth_da.representor_ports[i]; 2082c1d14583SBruce Richardson struct rte_eth_dev *vf_rep_eth_dev; 2083c1d14583SBruce Richardson 2084c1d14583SBruce Richardson if (vf_id >= dcf_adapter->real_hw.num_vfs) { 2085c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "VF ID %u is out of range (0 ~ %u)", 2086c1d14583SBruce Richardson vf_id, dcf_adapter->real_hw.num_vfs - 1); 2087c1d14583SBruce Richardson ret = -EINVAL; 2088c1d14583SBruce Richardson break; 2089c1d14583SBruce Richardson } 2090c1d14583SBruce Richardson 2091c1d14583SBruce Richardson if (dcf_adapter->real_hw.vf_vsi_map[vf_id] == dcf_vsi_id) { 2092c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "VF ID %u is DCF's ID.", vf_id); 2093c1d14583SBruce Richardson ret = -EINVAL; 2094c1d14583SBruce Richardson break; 2095c1d14583SBruce Richardson } 2096c1d14583SBruce Richardson 2097c1d14583SBruce Richardson repr_param.vf_id = vf_id; 2098c1d14583SBruce Richardson snprintf(repr_name, sizeof(repr_name), "net_%s_representor_%u", 2099c1d14583SBruce Richardson pci_dev->device.name, vf_id); 2100c1d14583SBruce Richardson ret = rte_eth_dev_create(&pci_dev->device, repr_name, 2101c1d14583SBruce Richardson sizeof(struct ice_dcf_vf_repr), 2102c1d14583SBruce Richardson NULL, NULL, ice_dcf_vf_repr_init, 2103c1d14583SBruce Richardson &repr_param); 2104c1d14583SBruce Richardson if (ret) { 2105c1d14583SBruce Richardson PMD_DRV_LOG(ERR, "failed to create DCF VF representor %s", 2106c1d14583SBruce Richardson repr_name); 2107c1d14583SBruce Richardson break; 2108c1d14583SBruce Richardson } 2109c1d14583SBruce Richardson 2110c1d14583SBruce Richardson vf_rep_eth_dev = rte_eth_dev_allocated(repr_name); 2111c1d14583SBruce Richardson if (!vf_rep_eth_dev) { 2112c1d14583SBruce Richardson PMD_DRV_LOG(ERR, 2113c1d14583SBruce Richardson "Failed to find the ethdev for DCF VF representor: %s", 2114c1d14583SBruce Richardson repr_name); 2115c1d14583SBruce Richardson ret = -ENODEV; 2116c1d14583SBruce Richardson break; 2117c1d14583SBruce Richardson } 2118c1d14583SBruce Richardson 2119c1d14583SBruce Richardson dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev = vf_rep_eth_dev; 2120c1d14583SBruce Richardson dcf_adapter->num_reprs++; 2121c1d14583SBruce Richardson } 2122c1d14583SBruce Richardson 2123c1d14583SBruce Richardson return ret; 2124c1d14583SBruce Richardson } 2125c1d14583SBruce Richardson 2126c1d14583SBruce Richardson static int 2127c1d14583SBruce Richardson eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev) 2128c1d14583SBruce Richardson { 2129c1d14583SBruce Richardson struct rte_eth_dev *eth_dev; 2130c1d14583SBruce Richardson 2131c1d14583SBruce Richardson eth_dev = rte_eth_dev_allocated(pci_dev->device.name); 2132c1d14583SBruce Richardson if (!eth_dev) 2133c1d14583SBruce Richardson return 0; 2134c1d14583SBruce Richardson 2135c1d14583SBruce Richardson if (rte_eth_dev_is_repr(eth_dev)) 2136c1d14583SBruce Richardson return rte_eth_dev_pci_generic_remove(pci_dev, 2137c1d14583SBruce Richardson ice_dcf_vf_repr_uninit); 2138c1d14583SBruce Richardson else 2139c1d14583SBruce Richardson return rte_eth_dev_pci_generic_remove(pci_dev, 2140c1d14583SBruce Richardson ice_dcf_dev_uninit); 2141c1d14583SBruce Richardson } 2142c1d14583SBruce Richardson 2143c1d14583SBruce Richardson static const struct rte_pci_id pci_id_ice_dcf_map[] = { 2144c1d14583SBruce Richardson { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_ADAPTIVE_VF) }, 2145c1d14583SBruce Richardson { .vendor_id = 0, /* sentinel */ }, 2146c1d14583SBruce Richardson }; 2147c1d14583SBruce Richardson 2148c1d14583SBruce Richardson static struct rte_pci_driver rte_ice_dcf_pmd = { 2149c1d14583SBruce Richardson .id_table = pci_id_ice_dcf_map, 2150c1d14583SBruce Richardson .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 2151c1d14583SBruce Richardson .probe = eth_ice_dcf_pci_probe, 2152c1d14583SBruce Richardson .remove = eth_ice_dcf_pci_remove, 2153c1d14583SBruce Richardson }; 2154c1d14583SBruce Richardson 2155c1d14583SBruce Richardson RTE_PMD_REGISTER_PCI(net_ice_dcf, rte_ice_dcf_pmd); 2156c1d14583SBruce Richardson RTE_PMD_REGISTER_PCI_TABLE(net_ice_dcf, pci_id_ice_dcf_map); 2157c1d14583SBruce Richardson RTE_PMD_REGISTER_KMOD_DEP(net_ice_dcf, "* igb_uio | vfio-pci"); 2158c1d14583SBruce Richardson RTE_PMD_REGISTER_PARAM_STRING(net_ice_dcf, "cap=dcf"); 2159