net/ice: add stop flag for device start/stop
[dpdk.git] / drivers / net / ice / ice_dcf_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4
5 #include <errno.h>
6 #include <stdbool.h>
7 #include <sys/types.h>
8 #include <sys/ioctl.h>
9 #include <unistd.h>
10
11 #include <rte_interrupts.h>
12 #include <rte_debug.h>
13 #include <rte_pci.h>
14 #include <rte_atomic.h>
15 #include <rte_eal.h>
16 #include <rte_ether.h>
17 #include <rte_ethdev_pci.h>
18 #include <rte_kvargs.h>
19 #include <rte_malloc.h>
20 #include <rte_memzone.h>
21 #include <rte_dev.h>
22
23 #include <iavf_devids.h>
24
25 #include "ice_generic_flow.h"
26 #include "ice_dcf_ethdev.h"
27 #include "ice_rxtx.h"
28
29 static uint16_t
30 ice_dcf_recv_pkts(__rte_unused void *rx_queue,
31                   __rte_unused struct rte_mbuf **bufs,
32                   __rte_unused uint16_t nb_pkts)
33 {
34         return 0;
35 }
36
37 static uint16_t
38 ice_dcf_xmit_pkts(__rte_unused void *tx_queue,
39                   __rte_unused struct rte_mbuf **bufs,
40                   __rte_unused uint16_t nb_pkts)
41 {
42         return 0;
43 }
44
45 static int
46 ice_dcf_dev_start(struct rte_eth_dev *dev)
47 {
48         struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
49         struct ice_adapter *ad = &dcf_ad->parent;
50
51         ad->pf.adapter_stopped = 0;
52
53         dev->data->dev_link.link_status = ETH_LINK_UP;
54
55         return 0;
56 }
57
58 static void
59 ice_dcf_dev_stop(struct rte_eth_dev *dev)
60 {
61         struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
62         struct ice_adapter *ad = &dcf_ad->parent;
63
64         if (ad->pf.adapter_stopped == 1) {
65                 PMD_DRV_LOG(DEBUG, "Port is already stopped");
66                 return;
67         }
68
69         dev->data->dev_link.link_status = ETH_LINK_DOWN;
70         ad->pf.adapter_stopped = 1;
71 }
72
73 static int
74 ice_dcf_dev_configure(struct rte_eth_dev *dev)
75 {
76         struct ice_dcf_adapter *dcf_ad = dev->data->dev_private;
77         struct ice_adapter *ad = &dcf_ad->parent;
78
79         ad->rx_bulk_alloc_allowed = true;
80         ad->tx_simple_allowed = true;
81
82         if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
83                 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;
84
85         return 0;
86 }
87
88 static int
89 ice_dcf_dev_info_get(struct rte_eth_dev *dev,
90                      struct rte_eth_dev_info *dev_info)
91 {
92         struct ice_dcf_adapter *adapter = dev->data->dev_private;
93         struct ice_dcf_hw *hw = &adapter->real_hw;
94
95         dev_info->max_mac_addrs = 1;
96         dev_info->max_rx_queues = hw->vsi_res->num_queue_pairs;
97         dev_info->max_tx_queues = hw->vsi_res->num_queue_pairs;
98         dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN;
99         dev_info->max_rx_pktlen = ICE_FRAME_SIZE_MAX;
100         dev_info->hash_key_size = hw->vf_res->rss_key_size;
101         dev_info->reta_size = hw->vf_res->rss_lut_size;
102         dev_info->flow_type_rss_offloads = ICE_RSS_OFFLOAD_ALL;
103
104         dev_info->rx_offload_capa =
105                 DEV_RX_OFFLOAD_VLAN_STRIP |
106                 DEV_RX_OFFLOAD_IPV4_CKSUM |
107                 DEV_RX_OFFLOAD_UDP_CKSUM |
108                 DEV_RX_OFFLOAD_TCP_CKSUM |
109                 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
110                 DEV_RX_OFFLOAD_SCATTER |
111                 DEV_RX_OFFLOAD_JUMBO_FRAME |
112                 DEV_RX_OFFLOAD_VLAN_FILTER |
113                 DEV_RX_OFFLOAD_RSS_HASH;
114         dev_info->tx_offload_capa =
115                 DEV_TX_OFFLOAD_VLAN_INSERT |
116                 DEV_TX_OFFLOAD_IPV4_CKSUM |
117                 DEV_TX_OFFLOAD_UDP_CKSUM |
118                 DEV_TX_OFFLOAD_TCP_CKSUM |
119                 DEV_TX_OFFLOAD_SCTP_CKSUM |
120                 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
121                 DEV_TX_OFFLOAD_TCP_TSO |
122                 DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
123                 DEV_TX_OFFLOAD_GRE_TNL_TSO |
124                 DEV_TX_OFFLOAD_IPIP_TNL_TSO |
125                 DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
126                 DEV_TX_OFFLOAD_MULTI_SEGS;
127
128         dev_info->default_rxconf = (struct rte_eth_rxconf) {
129                 .rx_thresh = {
130                         .pthresh = ICE_DEFAULT_RX_PTHRESH,
131                         .hthresh = ICE_DEFAULT_RX_HTHRESH,
132                         .wthresh = ICE_DEFAULT_RX_WTHRESH,
133                 },
134                 .rx_free_thresh = ICE_DEFAULT_RX_FREE_THRESH,
135                 .rx_drop_en = 0,
136                 .offloads = 0,
137         };
138
139         dev_info->default_txconf = (struct rte_eth_txconf) {
140                 .tx_thresh = {
141                         .pthresh = ICE_DEFAULT_TX_PTHRESH,
142                         .hthresh = ICE_DEFAULT_TX_HTHRESH,
143                         .wthresh = ICE_DEFAULT_TX_WTHRESH,
144                 },
145                 .tx_free_thresh = ICE_DEFAULT_TX_FREE_THRESH,
146                 .tx_rs_thresh = ICE_DEFAULT_TX_RSBIT_THRESH,
147                 .offloads = 0,
148         };
149
150         dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
151                 .nb_max = ICE_MAX_RING_DESC,
152                 .nb_min = ICE_MIN_RING_DESC,
153                 .nb_align = ICE_ALIGN_RING_DESC,
154         };
155
156         dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
157                 .nb_max = ICE_MAX_RING_DESC,
158                 .nb_min = ICE_MIN_RING_DESC,
159                 .nb_align = ICE_ALIGN_RING_DESC,
160         };
161
162         return 0;
163 }
164
165 static int
166 ice_dcf_stats_get(__rte_unused struct rte_eth_dev *dev,
167                   __rte_unused struct rte_eth_stats *igb_stats)
168 {
169         return 0;
170 }
171
172 static int
173 ice_dcf_stats_reset(__rte_unused struct rte_eth_dev *dev)
174 {
175         return 0;
176 }
177
178 static int
179 ice_dcf_dev_promiscuous_enable(__rte_unused struct rte_eth_dev *dev)
180 {
181         return 0;
182 }
183
184 static int
185 ice_dcf_dev_promiscuous_disable(__rte_unused struct rte_eth_dev *dev)
186 {
187         return 0;
188 }
189
190 static int
191 ice_dcf_dev_allmulticast_enable(__rte_unused struct rte_eth_dev *dev)
192 {
193         return 0;
194 }
195
196 static int
197 ice_dcf_dev_allmulticast_disable(__rte_unused struct rte_eth_dev *dev)
198 {
199         return 0;
200 }
201
202 static int
203 ice_dcf_dev_filter_ctrl(struct rte_eth_dev *dev,
204                         enum rte_filter_type filter_type,
205                         enum rte_filter_op filter_op,
206                         void *arg)
207 {
208         int ret = 0;
209
210         if (!dev)
211                 return -EINVAL;
212
213         switch (filter_type) {
214         case RTE_ETH_FILTER_GENERIC:
215                 if (filter_op != RTE_ETH_FILTER_GET)
216                         return -EINVAL;
217                 *(const void **)arg = &ice_flow_ops;
218                 break;
219
220         default:
221                 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
222                             filter_type);
223                 ret = -EINVAL;
224                 break;
225         }
226
227         return ret;
228 }
229
230 static void
231 ice_dcf_dev_close(struct rte_eth_dev *dev)
232 {
233         struct ice_dcf_adapter *adapter = dev->data->dev_private;
234
235         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
236                 return;
237
238         dev->dev_ops = NULL;
239         dev->rx_pkt_burst = NULL;
240         dev->tx_pkt_burst = NULL;
241
242         ice_dcf_uninit_parent_adapter(dev);
243         ice_dcf_uninit_hw(dev, &adapter->real_hw);
244 }
245
246 static int
247 ice_dcf_link_update(__rte_unused struct rte_eth_dev *dev,
248                     __rte_unused int wait_to_complete)
249 {
250         return 0;
251 }
252
253 static const struct eth_dev_ops ice_dcf_eth_dev_ops = {
254         .dev_start               = ice_dcf_dev_start,
255         .dev_stop                = ice_dcf_dev_stop,
256         .dev_close               = ice_dcf_dev_close,
257         .dev_configure           = ice_dcf_dev_configure,
258         .dev_infos_get           = ice_dcf_dev_info_get,
259         .rx_queue_setup          = ice_rx_queue_setup,
260         .tx_queue_setup          = ice_tx_queue_setup,
261         .rx_queue_release        = ice_rx_queue_release,
262         .tx_queue_release        = ice_tx_queue_release,
263         .link_update             = ice_dcf_link_update,
264         .stats_get               = ice_dcf_stats_get,
265         .stats_reset             = ice_dcf_stats_reset,
266         .promiscuous_enable      = ice_dcf_dev_promiscuous_enable,
267         .promiscuous_disable     = ice_dcf_dev_promiscuous_disable,
268         .allmulticast_enable     = ice_dcf_dev_allmulticast_enable,
269         .allmulticast_disable    = ice_dcf_dev_allmulticast_disable,
270         .filter_ctrl             = ice_dcf_dev_filter_ctrl,
271 };
272
273 static int
274 ice_dcf_dev_init(struct rte_eth_dev *eth_dev)
275 {
276         struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
277
278         eth_dev->dev_ops = &ice_dcf_eth_dev_ops;
279         eth_dev->rx_pkt_burst = ice_dcf_recv_pkts;
280         eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts;
281
282         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
283                 return 0;
284
285         eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
286
287         adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg;
288         if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) {
289                 PMD_INIT_LOG(ERR, "Failed to init DCF hardware");
290                 return -1;
291         }
292
293         if (ice_dcf_init_parent_adapter(eth_dev) != 0) {
294                 PMD_INIT_LOG(ERR, "Failed to init DCF parent adapter");
295                 ice_dcf_uninit_hw(eth_dev, &adapter->real_hw);
296                 return -1;
297         }
298
299         return 0;
300 }
301
302 static int
303 ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev)
304 {
305         ice_dcf_dev_close(eth_dev);
306
307         return 0;
308 }
309
310 static int
311 ice_dcf_cap_check_handler(__rte_unused const char *key,
312                           const char *value, __rte_unused void *opaque)
313 {
314         if (strcmp(value, "dcf"))
315                 return -1;
316
317         return 0;
318 }
319
320 static int
321 ice_dcf_cap_selected(struct rte_devargs *devargs)
322 {
323         struct rte_kvargs *kvlist;
324         const char *key = "cap";
325         int ret = 0;
326
327         if (devargs == NULL)
328                 return 0;
329
330         kvlist = rte_kvargs_parse(devargs->args, NULL);
331         if (kvlist == NULL)
332                 return 0;
333
334         if (!rte_kvargs_count(kvlist, key))
335                 goto exit;
336
337         /* dcf capability selected when there's a key-value pair: cap=dcf */
338         if (rte_kvargs_process(kvlist, key,
339                                ice_dcf_cap_check_handler, NULL) < 0)
340                 goto exit;
341
342         ret = 1;
343
344 exit:
345         rte_kvargs_free(kvlist);
346         return ret;
347 }
348
349 static int eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
350                              struct rte_pci_device *pci_dev)
351 {
352         if (!ice_dcf_cap_selected(pci_dev->device.devargs))
353                 return 1;
354
355         return rte_eth_dev_pci_generic_probe(pci_dev,
356                                              sizeof(struct ice_dcf_adapter),
357                                              ice_dcf_dev_init);
358 }
359
360 static int eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev)
361 {
362         return rte_eth_dev_pci_generic_remove(pci_dev, ice_dcf_dev_uninit);
363 }
364
365 static const struct rte_pci_id pci_id_ice_dcf_map[] = {
366         { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_ADAPTIVE_VF) },
367         { .vendor_id = 0, /* sentinel */ },
368 };
369
370 static struct rte_pci_driver rte_ice_dcf_pmd = {
371         .id_table = pci_id_ice_dcf_map,
372         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
373         .probe = eth_ice_dcf_pci_probe,
374         .remove = eth_ice_dcf_pci_remove,
375 };
376
377 RTE_PMD_REGISTER_PCI(net_ice_dcf, rte_ice_dcf_pmd);
378 RTE_PMD_REGISTER_PCI_TABLE(net_ice_dcf, pci_id_ice_dcf_map);
379 RTE_PMD_REGISTER_KMOD_DEP(net_ice_dcf, "* igb_uio | vfio-pci");
380 RTE_PMD_REGISTER_PARAM_STRING(net_ice_dcf, "cap=dcf");