1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016-2018 Microsoft Corporation
3 * Copyright(c) 2013-2016 Brocade Communications Systems, Inc.
13 #include <rte_ethdev.h>
14 #include <rte_memcpy.h>
15 #include <rte_string_fns.h>
16 #include <rte_memzone.h>
17 #include <rte_devargs.h>
18 #include <rte_malloc.h>
19 #include <rte_kvargs.h>
20 #include <rte_atomic.h>
21 #include <rte_branch_prediction.h>
22 #include <rte_ether.h>
23 #include <rte_ethdev_driver.h>
24 #include <rte_cycles.h>
25 #include <rte_errno.h>
26 #include <rte_memory.h>
29 #include <rte_bus_vmbus.h>
37 #define HN_TX_OFFLOAD_CAPS (DEV_TX_OFFLOAD_IPV4_CKSUM | \
38 DEV_TX_OFFLOAD_TCP_CKSUM | \
39 DEV_TX_OFFLOAD_UDP_CKSUM | \
40 DEV_TX_OFFLOAD_TCP_TSO | \
41 DEV_TX_OFFLOAD_MULTI_SEGS | \
42 DEV_TX_OFFLOAD_VLAN_INSERT)
44 #define HN_RX_OFFLOAD_CAPS (DEV_RX_OFFLOAD_CHECKSUM | \
45 DEV_RX_OFFLOAD_VLAN_STRIP | \
46 DEV_RX_OFFLOAD_RSS_HASH)
49 int hn_logtype_driver
;
51 struct hn_xstats_name_off
{
52 char name
[RTE_ETH_XSTATS_NAME_SIZE
];
56 static const struct hn_xstats_name_off hn_stat_strings
[] = {
57 { "good_packets", offsetof(struct hn_stats
, packets
) },
58 { "good_bytes", offsetof(struct hn_stats
, bytes
) },
59 { "errors", offsetof(struct hn_stats
, errors
) },
60 { "ring full", offsetof(struct hn_stats
, ring_full
) },
61 { "multicast_packets", offsetof(struct hn_stats
, multicast
) },
62 { "broadcast_packets", offsetof(struct hn_stats
, broadcast
) },
63 { "undersize_packets", offsetof(struct hn_stats
, size_bins
[0]) },
64 { "size_64_packets", offsetof(struct hn_stats
, size_bins
[1]) },
65 { "size_65_127_packets", offsetof(struct hn_stats
, size_bins
[2]) },
66 { "size_128_255_packets", offsetof(struct hn_stats
, size_bins
[3]) },
67 { "size_256_511_packets", offsetof(struct hn_stats
, size_bins
[4]) },
68 { "size_512_1023_packets", offsetof(struct hn_stats
, size_bins
[5]) },
69 { "size_1024_1518_packets", offsetof(struct hn_stats
, size_bins
[6]) },
70 { "size_1519_max_packets", offsetof(struct hn_stats
, size_bins
[7]) },
73 /* The default RSS key.
74 * This value is the same as MLX5 so that flows will be
75 * received on same path for both VF and synthetic NIC.
77 static const uint8_t rss_default_key
[NDIS_HASH_KEYSIZE_TOEPLITZ
] = {
78 0x2c, 0xc6, 0x81, 0xd1, 0x5b, 0xdb, 0xf4, 0xf7,
79 0xfc, 0xa2, 0x83, 0x19, 0xdb, 0x1a, 0x3e, 0x94,
80 0x6b, 0x9e, 0x38, 0xd9, 0x2c, 0x9c, 0x03, 0xd1,
81 0xad, 0x99, 0x44, 0xa7, 0xd9, 0x56, 0x3d, 0x59,
82 0x06, 0x3c, 0x25, 0xf3, 0xfc, 0x1f, 0xdc, 0x2a,
85 static struct rte_eth_dev
*
86 eth_dev_vmbus_allocate(struct rte_vmbus_device
*dev
, size_t private_data_size
)
88 struct rte_eth_dev
*eth_dev
;
94 name
= dev
->device
.name
;
96 if (rte_eal_process_type() == RTE_PROC_PRIMARY
) {
97 eth_dev
= rte_eth_dev_allocate(name
);
99 PMD_DRV_LOG(NOTICE
, "can not allocate rte ethdev");
103 if (private_data_size
) {
104 eth_dev
->data
->dev_private
=
105 rte_zmalloc_socket(name
, private_data_size
,
106 RTE_CACHE_LINE_SIZE
, dev
->device
.numa_node
);
107 if (!eth_dev
->data
->dev_private
) {
108 PMD_DRV_LOG(NOTICE
, "can not allocate driver data");
109 rte_eth_dev_release_port(eth_dev
);
114 eth_dev
= rte_eth_dev_attach_secondary(name
);
116 PMD_DRV_LOG(NOTICE
, "can not attach secondary");
121 eth_dev
->device
= &dev
->device
;
123 /* interrupt is simulated */
124 dev
->intr_handle
.type
= RTE_INTR_HANDLE_EXT
;
125 eth_dev
->data
->dev_flags
|= RTE_ETH_DEV_INTR_LSC
;
126 eth_dev
->intr_handle
= &dev
->intr_handle
;
128 /* allow ethdev to remove on close */
129 eth_dev
->data
->dev_flags
|= RTE_ETH_DEV_CLOSE_REMOVE
;
135 eth_dev_vmbus_release(struct rte_eth_dev
*eth_dev
)
137 /* free ether device */
138 rte_eth_dev_release_port(eth_dev
);
140 eth_dev
->device
= NULL
;
141 eth_dev
->intr_handle
= NULL
;
144 /* handle "latency=X" from devargs */
145 static int hn_set_latency(const char *key
, const char *value
, void *opaque
)
147 struct hn_data
*hv
= opaque
;
152 lat
= strtoul(value
, &endp
, 0);
154 if (*value
== '\0' || *endp
!= '\0') {
155 PMD_DRV_LOG(ERR
, "invalid parameter %s=%s", key
, value
);
159 PMD_DRV_LOG(DEBUG
, "set latency %lu usec", lat
);
161 hv
->latency
= lat
* 1000; /* usec to nsec */
165 /* Parse device arguments */
166 static int hn_parse_args(const struct rte_eth_dev
*dev
)
168 struct hn_data
*hv
= dev
->data
->dev_private
;
169 struct rte_devargs
*devargs
= dev
->device
->devargs
;
170 static const char * const valid_keys
[] = {
174 struct rte_kvargs
*kvlist
;
180 PMD_INIT_LOG(DEBUG
, "device args %s %s",
181 devargs
->name
, devargs
->args
);
183 kvlist
= rte_kvargs_parse(devargs
->args
, valid_keys
);
185 PMD_DRV_LOG(NOTICE
, "invalid parameters");
189 ret
= rte_kvargs_process(kvlist
, "latency", hn_set_latency
, hv
);
191 PMD_DRV_LOG(ERR
, "Unable to process latency arg\n");
193 rte_kvargs_free(kvlist
);
197 /* Update link status.
198 * Note: the DPDK definition of "wait_to_complete"
199 * means block this call until link is up.
200 * which is not worth supporting.
203 hn_dev_link_update(struct rte_eth_dev
*dev
,
204 int wait_to_complete
)
206 struct hn_data
*hv
= dev
->data
->dev_private
;
207 struct rte_eth_link link
, old
;
210 old
= dev
->data
->dev_link
;
212 error
= hn_rndis_get_linkstatus(hv
);
216 hn_rndis_get_linkspeed(hv
);
218 hn_vf_link_update(dev
, wait_to_complete
);
220 link
= (struct rte_eth_link
) {
221 .link_duplex
= ETH_LINK_FULL_DUPLEX
,
222 .link_autoneg
= ETH_LINK_SPEED_FIXED
,
223 .link_speed
= hv
->link_speed
/ 10000,
226 if (hv
->link_status
== NDIS_MEDIA_STATE_CONNECTED
)
227 link
.link_status
= ETH_LINK_UP
;
229 link
.link_status
= ETH_LINK_DOWN
;
231 if (old
.link_status
== link
.link_status
)
234 PMD_INIT_LOG(DEBUG
, "Port %d is %s", dev
->data
->port_id
,
235 (link
.link_status
== ETH_LINK_UP
) ? "up" : "down");
237 return rte_eth_linkstatus_set(dev
, &link
);
240 static int hn_dev_info_get(struct rte_eth_dev
*dev
,
241 struct rte_eth_dev_info
*dev_info
)
243 struct hn_data
*hv
= dev
->data
->dev_private
;
246 dev_info
->speed_capa
= ETH_LINK_SPEED_10G
;
247 dev_info
->min_rx_bufsize
= HN_MIN_RX_BUF_SIZE
;
248 dev_info
->max_rx_pktlen
= HN_MAX_XFER_LEN
;
249 dev_info
->max_mac_addrs
= 1;
251 dev_info
->hash_key_size
= NDIS_HASH_KEYSIZE_TOEPLITZ
;
252 dev_info
->flow_type_rss_offloads
= hv
->rss_offloads
;
253 dev_info
->reta_size
= ETH_RSS_RETA_SIZE_128
;
255 dev_info
->max_rx_queues
= hv
->max_queues
;
256 dev_info
->max_tx_queues
= hv
->max_queues
;
258 dev_info
->tx_desc_lim
.nb_min
= 1;
259 dev_info
->tx_desc_lim
.nb_max
= 4096;
261 if (rte_eal_process_type() != RTE_PROC_PRIMARY
)
264 /* fills in rx and tx offload capability */
265 rc
= hn_rndis_get_offload(hv
, dev_info
);
269 /* merges the offload and queues of vf */
270 return hn_vf_info_get(hv
, dev_info
);
273 static int hn_rss_reta_update(struct rte_eth_dev
*dev
,
274 struct rte_eth_rss_reta_entry64
*reta_conf
,
277 struct hn_data
*hv
= dev
->data
->dev_private
;
281 PMD_INIT_FUNC_TRACE();
283 if (reta_size
!= NDIS_HASH_INDCNT
) {
284 PMD_DRV_LOG(ERR
, "Hash lookup table size does not match NDIS");
288 for (i
= 0; i
< NDIS_HASH_INDCNT
; i
++) {
289 uint16_t idx
= i
/ RTE_RETA_GROUP_SIZE
;
290 uint16_t shift
= i
% RTE_RETA_GROUP_SIZE
;
291 uint64_t mask
= (uint64_t)1 << shift
;
293 if (reta_conf
[idx
].mask
& mask
)
294 hv
->rss_ind
[i
] = reta_conf
[idx
].reta
[shift
];
297 err
= hn_rndis_conf_rss(hv
, NDIS_RSS_FLAG_DISABLE
);
300 "rss disable failed");
304 err
= hn_rndis_conf_rss(hv
, 0);
307 "reta reconfig failed");
311 return hn_vf_reta_hash_update(dev
, reta_conf
, reta_size
);
314 static int hn_rss_reta_query(struct rte_eth_dev
*dev
,
315 struct rte_eth_rss_reta_entry64
*reta_conf
,
318 struct hn_data
*hv
= dev
->data
->dev_private
;
321 PMD_INIT_FUNC_TRACE();
323 if (reta_size
!= NDIS_HASH_INDCNT
) {
324 PMD_DRV_LOG(ERR
, "Hash lookup table size does not match NDIS");
328 for (i
= 0; i
< NDIS_HASH_INDCNT
; i
++) {
329 uint16_t idx
= i
/ RTE_RETA_GROUP_SIZE
;
330 uint16_t shift
= i
% RTE_RETA_GROUP_SIZE
;
331 uint64_t mask
= (uint64_t)1 << shift
;
333 if (reta_conf
[idx
].mask
& mask
)
334 reta_conf
[idx
].reta
[shift
] = hv
->rss_ind
[i
];
339 static void hn_rss_hash_init(struct hn_data
*hv
,
340 const struct rte_eth_rss_conf
*rss_conf
)
342 /* Convert from DPDK RSS hash flags to NDIS hash flags */
343 hv
->rss_hash
= NDIS_HASH_FUNCTION_TOEPLITZ
;
345 if (rss_conf
->rss_hf
& ETH_RSS_IPV4
)
346 hv
->rss_hash
|= NDIS_HASH_IPV4
;
347 if (rss_conf
->rss_hf
& ETH_RSS_NONFRAG_IPV4_TCP
)
348 hv
->rss_hash
|= NDIS_HASH_TCP_IPV4
;
349 if (rss_conf
->rss_hf
& ETH_RSS_IPV6
)
350 hv
->rss_hash
|= NDIS_HASH_IPV6
;
351 if (rss_conf
->rss_hf
& ETH_RSS_IPV6_EX
)
352 hv
->rss_hash
|= NDIS_HASH_IPV6_EX
;
353 if (rss_conf
->rss_hf
& ETH_RSS_NONFRAG_IPV6_TCP
)
354 hv
->rss_hash
|= NDIS_HASH_TCP_IPV6
;
355 if (rss_conf
->rss_hf
& ETH_RSS_IPV6_TCP_EX
)
356 hv
->rss_hash
|= NDIS_HASH_TCP_IPV6_EX
;
358 memcpy(hv
->rss_key
, rss_conf
->rss_key
? : rss_default_key
,
359 NDIS_HASH_KEYSIZE_TOEPLITZ
);
362 static int hn_rss_hash_update(struct rte_eth_dev
*dev
,
363 struct rte_eth_rss_conf
*rss_conf
)
365 struct hn_data
*hv
= dev
->data
->dev_private
;
368 PMD_INIT_FUNC_TRACE();
370 err
= hn_rndis_conf_rss(hv
, NDIS_RSS_FLAG_DISABLE
);
373 "rss disable failed");
377 hn_rss_hash_init(hv
, rss_conf
);
379 if (rss_conf
->rss_hf
!= 0) {
380 err
= hn_rndis_conf_rss(hv
, 0);
383 "rss reconfig failed (RSS disabled)");
388 return hn_vf_rss_hash_update(dev
, rss_conf
);
391 static int hn_rss_hash_conf_get(struct rte_eth_dev
*dev
,
392 struct rte_eth_rss_conf
*rss_conf
)
394 struct hn_data
*hv
= dev
->data
->dev_private
;
396 PMD_INIT_FUNC_TRACE();
398 if (hv
->ndis_ver
< NDIS_VERSION_6_20
) {
399 PMD_DRV_LOG(DEBUG
, "RSS not supported on this host");
403 rss_conf
->rss_key_len
= NDIS_HASH_KEYSIZE_TOEPLITZ
;
404 if (rss_conf
->rss_key
)
405 memcpy(rss_conf
->rss_key
, hv
->rss_key
,
406 NDIS_HASH_KEYSIZE_TOEPLITZ
);
408 rss_conf
->rss_hf
= 0;
409 if (hv
->rss_hash
& NDIS_HASH_IPV4
)
410 rss_conf
->rss_hf
|= ETH_RSS_IPV4
;
412 if (hv
->rss_hash
& NDIS_HASH_TCP_IPV4
)
413 rss_conf
->rss_hf
|= ETH_RSS_NONFRAG_IPV4_TCP
;
415 if (hv
->rss_hash
& NDIS_HASH_IPV6
)
416 rss_conf
->rss_hf
|= ETH_RSS_IPV6
;
418 if (hv
->rss_hash
& NDIS_HASH_IPV6_EX
)
419 rss_conf
->rss_hf
|= ETH_RSS_IPV6_EX
;
421 if (hv
->rss_hash
& NDIS_HASH_TCP_IPV6
)
422 rss_conf
->rss_hf
|= ETH_RSS_NONFRAG_IPV6_TCP
;
424 if (hv
->rss_hash
& NDIS_HASH_TCP_IPV6_EX
)
425 rss_conf
->rss_hf
|= ETH_RSS_IPV6_TCP_EX
;
431 hn_dev_promiscuous_enable(struct rte_eth_dev
*dev
)
433 struct hn_data
*hv
= dev
->data
->dev_private
;
435 hn_rndis_set_rxfilter(hv
, NDIS_PACKET_TYPE_PROMISCUOUS
);
436 return hn_vf_promiscuous_enable(dev
);
440 hn_dev_promiscuous_disable(struct rte_eth_dev
*dev
)
442 struct hn_data
*hv
= dev
->data
->dev_private
;
445 filter
= NDIS_PACKET_TYPE_DIRECTED
| NDIS_PACKET_TYPE_BROADCAST
;
446 if (dev
->data
->all_multicast
)
447 filter
|= NDIS_PACKET_TYPE_ALL_MULTICAST
;
448 hn_rndis_set_rxfilter(hv
, filter
);
449 return hn_vf_promiscuous_disable(dev
);
453 hn_dev_allmulticast_enable(struct rte_eth_dev
*dev
)
455 struct hn_data
*hv
= dev
->data
->dev_private
;
457 hn_rndis_set_rxfilter(hv
, NDIS_PACKET_TYPE_DIRECTED
|
458 NDIS_PACKET_TYPE_ALL_MULTICAST
|
459 NDIS_PACKET_TYPE_BROADCAST
);
460 return hn_vf_allmulticast_enable(dev
);
464 hn_dev_allmulticast_disable(struct rte_eth_dev
*dev
)
466 struct hn_data
*hv
= dev
->data
->dev_private
;
468 hn_rndis_set_rxfilter(hv
, NDIS_PACKET_TYPE_DIRECTED
|
469 NDIS_PACKET_TYPE_BROADCAST
);
470 return hn_vf_allmulticast_disable(dev
);
474 hn_dev_mc_addr_list(struct rte_eth_dev
*dev
,
475 struct rte_ether_addr
*mc_addr_set
,
478 /* No filtering on the synthetic path, but can do it on VF */
479 return hn_vf_mc_addr_list(dev
, mc_addr_set
, nb_mc_addr
);
482 /* Setup shared rx/tx queue data */
483 static int hn_subchan_configure(struct hn_data
*hv
,
486 struct vmbus_channel
*primary
= hn_primary_chan(hv
);
488 unsigned int retry
= 0;
491 "open %u subchannels", subchan
);
493 /* Send create sub channels command */
494 err
= hn_nvs_alloc_subchans(hv
, &subchan
);
498 while (subchan
> 0) {
499 struct vmbus_channel
*new_sc
;
502 err
= rte_vmbus_subchan_open(primary
, &new_sc
);
503 if (err
== -ENOENT
&& ++retry
< 1000) {
504 /* This can happen if not ready yet */
511 "open subchannel failed: %d", err
);
515 rte_vmbus_set_latency(hv
->vmbus
, new_sc
, hv
->latency
);
518 chn_index
= rte_vmbus_sub_channel_index(new_sc
);
519 if (chn_index
== 0 || chn_index
> hv
->max_queues
) {
521 "Invalid subchannel offermsg channel %u",
526 PMD_DRV_LOG(DEBUG
, "new sub channel %u", chn_index
);
527 hv
->channels
[chn_index
] = new_sc
;
534 static int hn_dev_configure(struct rte_eth_dev
*dev
)
536 struct rte_eth_conf
*dev_conf
= &dev
->data
->dev_conf
;
537 struct rte_eth_rss_conf
*rss_conf
= &dev_conf
->rx_adv_conf
.rss_conf
;
538 const struct rte_eth_rxmode
*rxmode
= &dev_conf
->rxmode
;
539 const struct rte_eth_txmode
*txmode
= &dev_conf
->txmode
;
540 struct hn_data
*hv
= dev
->data
->dev_private
;
541 uint64_t unsupported
;
544 PMD_INIT_FUNC_TRACE();
546 if (dev_conf
->rxmode
.mq_mode
& ETH_MQ_RX_RSS_FLAG
)
547 dev_conf
->rxmode
.offloads
|= DEV_RX_OFFLOAD_RSS_HASH
;
549 unsupported
= txmode
->offloads
& ~HN_TX_OFFLOAD_CAPS
;
552 "unsupported TX offload: %#" PRIx64
,
557 unsupported
= rxmode
->offloads
& ~HN_RX_OFFLOAD_CAPS
;
560 "unsupported RX offload: %#" PRIx64
,
565 hv
->vlan_strip
= !!(rxmode
->offloads
& DEV_RX_OFFLOAD_VLAN_STRIP
);
567 err
= hn_rndis_conf_offload(hv
, txmode
->offloads
,
571 "offload configure failed");
575 hv
->num_queues
= RTE_MAX(dev
->data
->nb_rx_queues
,
576 dev
->data
->nb_tx_queues
);
578 for (i
= 0; i
< NDIS_HASH_INDCNT
; i
++)
579 hv
->rss_ind
[i
] = i
% dev
->data
->nb_rx_queues
;
581 hn_rss_hash_init(hv
, rss_conf
);
583 subchan
= hv
->num_queues
- 1;
585 err
= hn_subchan_configure(hv
, subchan
);
588 "subchannel configuration failed");
592 err
= hn_rndis_conf_rss(hv
, NDIS_RSS_FLAG_DISABLE
);
595 "rss disable failed");
599 if (rss_conf
->rss_hf
!= 0) {
600 err
= hn_rndis_conf_rss(hv
, 0);
603 "initial RSS config failed");
609 return hn_vf_configure(dev
, dev_conf
);
612 static int hn_dev_stats_get(struct rte_eth_dev
*dev
,
613 struct rte_eth_stats
*stats
)
617 hn_vf_stats_get(dev
, stats
);
619 for (i
= 0; i
< dev
->data
->nb_tx_queues
; i
++) {
620 const struct hn_tx_queue
*txq
= dev
->data
->tx_queues
[i
];
625 stats
->opackets
+= txq
->stats
.packets
;
626 stats
->obytes
+= txq
->stats
.bytes
;
627 stats
->oerrors
+= txq
->stats
.errors
;
629 if (i
< RTE_ETHDEV_QUEUE_STAT_CNTRS
) {
630 stats
->q_opackets
[i
] = txq
->stats
.packets
;
631 stats
->q_obytes
[i
] = txq
->stats
.bytes
;
635 for (i
= 0; i
< dev
->data
->nb_rx_queues
; i
++) {
636 const struct hn_rx_queue
*rxq
= dev
->data
->rx_queues
[i
];
641 stats
->ipackets
+= rxq
->stats
.packets
;
642 stats
->ibytes
+= rxq
->stats
.bytes
;
643 stats
->ierrors
+= rxq
->stats
.errors
;
644 stats
->imissed
+= rxq
->stats
.ring_full
;
646 if (i
< RTE_ETHDEV_QUEUE_STAT_CNTRS
) {
647 stats
->q_ipackets
[i
] = rxq
->stats
.packets
;
648 stats
->q_ibytes
[i
] = rxq
->stats
.bytes
;
652 stats
->rx_nombuf
= dev
->data
->rx_mbuf_alloc_failed
;
657 hn_dev_stats_reset(struct rte_eth_dev
*dev
)
661 PMD_INIT_FUNC_TRACE();
663 for (i
= 0; i
< dev
->data
->nb_tx_queues
; i
++) {
664 struct hn_tx_queue
*txq
= dev
->data
->tx_queues
[i
];
668 memset(&txq
->stats
, 0, sizeof(struct hn_stats
));
671 for (i
= 0; i
< dev
->data
->nb_rx_queues
; i
++) {
672 struct hn_rx_queue
*rxq
= dev
->data
->rx_queues
[i
];
677 memset(&rxq
->stats
, 0, sizeof(struct hn_stats
));
684 hn_dev_xstats_reset(struct rte_eth_dev
*dev
)
688 ret
= hn_dev_stats_reset(dev
);
692 return hn_vf_xstats_reset(dev
);
696 hn_dev_xstats_count(struct rte_eth_dev
*dev
)
700 count
= dev
->data
->nb_tx_queues
* RTE_DIM(hn_stat_strings
);
701 count
+= dev
->data
->nb_rx_queues
* RTE_DIM(hn_stat_strings
);
703 ret
= hn_vf_xstats_get_names(dev
, NULL
, 0);
711 hn_dev_xstats_get_names(struct rte_eth_dev
*dev
,
712 struct rte_eth_xstat_name
*xstats_names
,
715 unsigned int i
, t
, count
= 0;
719 return hn_dev_xstats_count(dev
);
721 /* Note: limit checked in rte_eth_xstats_names() */
722 for (i
= 0; i
< dev
->data
->nb_tx_queues
; i
++) {
723 const struct hn_tx_queue
*txq
= dev
->data
->tx_queues
[i
];
731 for (t
= 0; t
< RTE_DIM(hn_stat_strings
); t
++)
732 snprintf(xstats_names
[count
++].name
,
733 RTE_ETH_XSTATS_NAME_SIZE
,
734 "tx_q%u_%s", i
, hn_stat_strings
[t
].name
);
737 for (i
= 0; i
< dev
->data
->nb_rx_queues
; i
++) {
738 const struct hn_rx_queue
*rxq
= dev
->data
->rx_queues
[i
];
746 for (t
= 0; t
< RTE_DIM(hn_stat_strings
); t
++)
747 snprintf(xstats_names
[count
++].name
,
748 RTE_ETH_XSTATS_NAME_SIZE
,
750 hn_stat_strings
[t
].name
);
753 ret
= hn_vf_xstats_get_names(dev
, xstats_names
+ count
,
762 hn_dev_xstats_get(struct rte_eth_dev
*dev
,
763 struct rte_eth_xstat
*xstats
,
766 unsigned int i
, t
, count
= 0;
767 const unsigned int nstats
= hn_dev_xstats_count(dev
);
771 PMD_INIT_FUNC_TRACE();
776 for (i
= 0; i
< dev
->data
->nb_tx_queues
; i
++) {
777 const struct hn_tx_queue
*txq
= dev
->data
->tx_queues
[i
];
782 stats
= (const char *)&txq
->stats
;
783 for (t
= 0; t
< RTE_DIM(hn_stat_strings
); t
++, count
++) {
784 xstats
[count
].id
= count
;
785 xstats
[count
].value
= *(const uint64_t *)
786 (stats
+ hn_stat_strings
[t
].offset
);
790 for (i
= 0; i
< dev
->data
->nb_rx_queues
; i
++) {
791 const struct hn_rx_queue
*rxq
= dev
->data
->rx_queues
[i
];
796 stats
= (const char *)&rxq
->stats
;
797 for (t
= 0; t
< RTE_DIM(hn_stat_strings
); t
++, count
++) {
798 xstats
[count
].id
= count
;
799 xstats
[count
].value
= *(const uint64_t *)
800 (stats
+ hn_stat_strings
[t
].offset
);
804 ret
= hn_vf_xstats_get(dev
, xstats
, count
, n
);
812 hn_dev_start(struct rte_eth_dev
*dev
)
814 struct hn_data
*hv
= dev
->data
->dev_private
;
817 PMD_INIT_FUNC_TRACE();
819 error
= hn_rndis_set_rxfilter(hv
,
820 NDIS_PACKET_TYPE_BROADCAST
|
821 NDIS_PACKET_TYPE_ALL_MULTICAST
|
822 NDIS_PACKET_TYPE_DIRECTED
);
826 error
= hn_vf_start(dev
);
828 hn_rndis_set_rxfilter(hv
, 0);
830 /* Initialize Link state */
832 hn_dev_link_update(dev
, 0);
838 hn_dev_stop(struct rte_eth_dev
*dev
)
840 struct hn_data
*hv
= dev
->data
->dev_private
;
842 PMD_INIT_FUNC_TRACE();
844 hn_rndis_set_rxfilter(hv
, 0);
849 hn_dev_close(struct rte_eth_dev
*dev
)
851 PMD_INIT_FUNC_TRACE();
854 hn_dev_free_queues(dev
);
857 static const struct eth_dev_ops hn_eth_dev_ops
= {
858 .dev_configure
= hn_dev_configure
,
859 .dev_start
= hn_dev_start
,
860 .dev_stop
= hn_dev_stop
,
861 .dev_close
= hn_dev_close
,
862 .dev_infos_get
= hn_dev_info_get
,
863 .dev_supported_ptypes_get
= hn_vf_supported_ptypes
,
864 .promiscuous_enable
= hn_dev_promiscuous_enable
,
865 .promiscuous_disable
= hn_dev_promiscuous_disable
,
866 .allmulticast_enable
= hn_dev_allmulticast_enable
,
867 .allmulticast_disable
= hn_dev_allmulticast_disable
,
868 .set_mc_addr_list
= hn_dev_mc_addr_list
,
869 .reta_update
= hn_rss_reta_update
,
870 .reta_query
= hn_rss_reta_query
,
871 .rss_hash_update
= hn_rss_hash_update
,
872 .rss_hash_conf_get
= hn_rss_hash_conf_get
,
873 .tx_queue_setup
= hn_dev_tx_queue_setup
,
874 .tx_queue_release
= hn_dev_tx_queue_release
,
875 .tx_done_cleanup
= hn_dev_tx_done_cleanup
,
876 .rx_queue_setup
= hn_dev_rx_queue_setup
,
877 .rx_queue_release
= hn_dev_rx_queue_release
,
878 .link_update
= hn_dev_link_update
,
879 .stats_get
= hn_dev_stats_get
,
880 .stats_reset
= hn_dev_stats_reset
,
881 .xstats_get
= hn_dev_xstats_get
,
882 .xstats_get_names
= hn_dev_xstats_get_names
,
883 .xstats_reset
= hn_dev_xstats_reset
,
887 * Setup connection between PMD and kernel.
890 hn_attach(struct hn_data
*hv
, unsigned int mtu
)
895 error
= hn_nvs_attach(hv
, mtu
);
900 error
= hn_rndis_attach(hv
);
906 * Under certain conditions on certain versions of Hyper-V,
907 * the RNDIS rxfilter is _not_ zero on the hypervisor side
908 * after the successful RNDIS initialization.
910 hn_rndis_set_rxfilter(hv
, NDIS_PACKET_TYPE_NONE
);
919 hn_detach(struct hn_data
*hv
)
926 eth_hn_dev_init(struct rte_eth_dev
*eth_dev
)
928 struct hn_data
*hv
= eth_dev
->data
->dev_private
;
929 struct rte_device
*device
= eth_dev
->device
;
930 struct rte_vmbus_device
*vmbus
;
931 unsigned int rxr_cnt
;
934 PMD_INIT_FUNC_TRACE();
936 vmbus
= container_of(device
, struct rte_vmbus_device
, device
);
937 eth_dev
->dev_ops
= &hn_eth_dev_ops
;
938 eth_dev
->tx_pkt_burst
= &hn_xmit_pkts
;
939 eth_dev
->rx_pkt_burst
= &hn_recv_pkts
;
942 * for secondary processes, we don't initialize any further as primary
943 * has already done this work.
945 if (rte_eal_process_type() != RTE_PROC_PRIMARY
)
948 /* Since Hyper-V only supports one MAC address */
949 eth_dev
->data
->mac_addrs
= rte_calloc("hv_mac", HN_MAX_MAC_ADDRS
,
950 sizeof(struct rte_ether_addr
), 0);
951 if (eth_dev
->data
->mac_addrs
== NULL
) {
953 "Failed to allocate memory store MAC addresses");
958 hv
->rxbuf_res
= &vmbus
->resource
[HV_RECV_BUF_MAP
];
959 hv
->chim_res
= &vmbus
->resource
[HV_SEND_BUF_MAP
];
960 hv
->port_id
= eth_dev
->data
->port_id
;
961 hv
->latency
= HN_CHAN_LATENCY_NS
;
963 rte_rwlock_init(&hv
->vf_lock
);
964 hv
->vf_port
= HN_INVALID_PORT
;
966 err
= hn_parse_args(eth_dev
);
970 strlcpy(hv
->owner
.name
, eth_dev
->device
->name
,
971 RTE_ETH_MAX_OWNER_NAME_LEN
);
972 err
= rte_eth_dev_owner_new(&hv
->owner
.id
);
974 PMD_INIT_LOG(ERR
, "Can not get owner id");
978 /* Initialize primary channel input for control operations */
979 err
= rte_vmbus_chan_open(vmbus
, &hv
->channels
[0]);
983 rte_vmbus_set_latency(hv
->vmbus
, hv
->channels
[0], hv
->latency
);
985 hv
->primary
= hn_rx_queue_alloc(hv
, 0,
986 eth_dev
->device
->numa_node
);
991 err
= hn_attach(hv
, RTE_ETHER_MTU
);
995 err
= hn_chim_init(eth_dev
);
999 err
= hn_rndis_get_eaddr(hv
, eth_dev
->data
->mac_addrs
->addr_bytes
);
1003 /* Multi queue requires later versions of windows server */
1004 if (hv
->nvs_ver
< NVS_VERSION_5
)
1007 max_chan
= rte_vmbus_max_channels(vmbus
);
1008 PMD_INIT_LOG(DEBUG
, "VMBus max channels %d", max_chan
);
1012 if (hn_rndis_query_rsscaps(hv
, &rxr_cnt
) != 0)
1015 hv
->max_queues
= RTE_MIN(rxr_cnt
, (unsigned int)max_chan
);
1017 /* If VF was reported but not added, do it now */
1018 if (hv
->vf_present
&& !hn_vf_attached(hv
)) {
1019 PMD_INIT_LOG(DEBUG
, "Adding VF device");
1021 err
= hn_vf_add(eth_dev
, hv
);
1029 PMD_INIT_LOG(NOTICE
, "device init failed");
1031 hn_chim_uninit(eth_dev
);
1037 eth_hn_dev_uninit(struct rte_eth_dev
*eth_dev
)
1039 struct hn_data
*hv
= eth_dev
->data
->dev_private
;
1042 PMD_INIT_FUNC_TRACE();
1044 if (rte_eal_process_type() != RTE_PROC_PRIMARY
)
1047 hn_dev_stop(eth_dev
);
1048 hn_dev_close(eth_dev
);
1050 eth_dev
->dev_ops
= NULL
;
1051 eth_dev
->tx_pkt_burst
= NULL
;
1052 eth_dev
->rx_pkt_burst
= NULL
;
1055 hn_chim_uninit(eth_dev
);
1056 rte_vmbus_chan_close(hv
->primary
->chan
);
1057 rte_free(hv
->primary
);
1058 ret
= rte_eth_dev_owner_delete(hv
->owner
.id
);
1065 static int eth_hn_probe(struct rte_vmbus_driver
*drv __rte_unused
,
1066 struct rte_vmbus_device
*dev
)
1068 struct rte_eth_dev
*eth_dev
;
1071 PMD_INIT_FUNC_TRACE();
1073 eth_dev
= eth_dev_vmbus_allocate(dev
, sizeof(struct hn_data
));
1077 ret
= eth_hn_dev_init(eth_dev
);
1079 eth_dev_vmbus_release(eth_dev
);
1081 rte_eth_dev_probing_finish(eth_dev
);
1086 static int eth_hn_remove(struct rte_vmbus_device
*dev
)
1088 struct rte_eth_dev
*eth_dev
;
1091 PMD_INIT_FUNC_TRACE();
1093 eth_dev
= rte_eth_dev_allocated(dev
->device
.name
);
1097 ret
= eth_hn_dev_uninit(eth_dev
);
1101 eth_dev_vmbus_release(eth_dev
);
1105 /* Network device GUID */
1106 static const rte_uuid_t hn_net_ids
[] = {
1107 /* f8615163-df3e-46c5-913f-f2d2f965ed0e */
1108 RTE_UUID_INIT(0xf8615163, 0xdf3e, 0x46c5, 0x913f, 0xf2d2f965ed0eULL
),
1112 static struct rte_vmbus_driver rte_netvsc_pmd
= {
1113 .id_table
= hn_net_ids
,
1114 .probe
= eth_hn_probe
,
1115 .remove
= eth_hn_remove
,
1118 RTE_PMD_REGISTER_VMBUS(net_netvsc
, rte_netvsc_pmd
);
1119 RTE_PMD_REGISTER_KMOD_DEP(net_netvsc
, "* uio_hv_generic");
1121 RTE_INIT(hn_init_log
)
1123 hn_logtype_init
= rte_log_register("pmd.net.netvsc.init");
1124 if (hn_logtype_init
>= 0)
1125 rte_log_set_level(hn_logtype_init
, RTE_LOG_NOTICE
);
1126 hn_logtype_driver
= rte_log_register("pmd.net.netvsc.driver");
1127 if (hn_logtype_driver
>= 0)
1128 rte_log_set_level(hn_logtype_driver
, RTE_LOG_NOTICE
);