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