xref: /dpdk/drivers/net/virtio/virtio.c (revision f5d4c819376b9a59e0f272e366fef0cd1fe9e4f2)
1b4f9a45aSMaxime Coquelin /* SPDX-License-Identifier: BSD-3-Clause
2b4f9a45aSMaxime Coquelin  * Copyright(c) 2010-2014 Intel Corporation
3b4f9a45aSMaxime Coquelin  * Copyright(c) 2020 Red Hat, Inc.
4b4f9a45aSMaxime Coquelin  */
5b4f9a45aSMaxime Coquelin 
6*f5d4c819SXueming Li #include <unistd.h>
7*f5d4c819SXueming Li 
8b4f9a45aSMaxime Coquelin #include "virtio.h"
9*f5d4c819SXueming Li #include "virtio_logs.h"
10b4f9a45aSMaxime Coquelin 
11b4f9a45aSMaxime Coquelin uint64_t
virtio_negotiate_features(struct virtio_hw * hw,uint64_t host_features)12b4f9a45aSMaxime Coquelin virtio_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
13b4f9a45aSMaxime Coquelin {
14b4f9a45aSMaxime Coquelin 	uint64_t features;
15b4f9a45aSMaxime Coquelin 
16b4f9a45aSMaxime Coquelin 	/*
17b4f9a45aSMaxime Coquelin 	 * Limit negotiated features to what the driver, virtqueue, and
18b4f9a45aSMaxime Coquelin 	 * host all support.
19b4f9a45aSMaxime Coquelin 	 */
20b4f9a45aSMaxime Coquelin 	features = host_features & hw->guest_features;
21b4f9a45aSMaxime Coquelin 	VIRTIO_OPS(hw)->set_features(hw, features);
22b4f9a45aSMaxime Coquelin 
23b4f9a45aSMaxime Coquelin 	return features;
24b4f9a45aSMaxime Coquelin }
25b4f9a45aSMaxime Coquelin 
269328e105SMaxime Coquelin 
279328e105SMaxime Coquelin void
virtio_read_dev_config(struct virtio_hw * hw,size_t offset,void * dst,int length)289328e105SMaxime Coquelin virtio_read_dev_config(struct virtio_hw *hw, size_t offset,
299328e105SMaxime Coquelin 		      void *dst, int length)
309328e105SMaxime Coquelin {
319328e105SMaxime Coquelin 	VIRTIO_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
329328e105SMaxime Coquelin }
339328e105SMaxime Coquelin 
349328e105SMaxime Coquelin void
virtio_write_dev_config(struct virtio_hw * hw,size_t offset,const void * src,int length)359328e105SMaxime Coquelin virtio_write_dev_config(struct virtio_hw *hw, size_t offset,
369328e105SMaxime Coquelin 		       const void *src, int length)
379328e105SMaxime Coquelin {
389328e105SMaxime Coquelin 	VIRTIO_OPS(hw)->write_dev_cfg(hw, offset, src, length);
399328e105SMaxime Coquelin }
409328e105SMaxime Coquelin 
419328e105SMaxime Coquelin void
virtio_reset(struct virtio_hw * hw)429328e105SMaxime Coquelin virtio_reset(struct virtio_hw *hw)
439328e105SMaxime Coquelin {
44*f5d4c819SXueming Li 	uint32_t retry = 0;
45*f5d4c819SXueming Li 
469328e105SMaxime Coquelin 	VIRTIO_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
47*f5d4c819SXueming Li 	/* Flush status write and wait device ready max 3 seconds. */
48*f5d4c819SXueming Li 	while (VIRTIO_OPS(hw)->get_status(hw) != VIRTIO_CONFIG_STATUS_RESET) {
49*f5d4c819SXueming Li 		if (retry++ > 3000) {
50*f5d4c819SXueming Li 			PMD_INIT_LOG(WARNING, "port %u device reset timeout", hw->port_id);
51*f5d4c819SXueming Li 			break;
52*f5d4c819SXueming Li 		}
53*f5d4c819SXueming Li 		usleep(1000L);
54*f5d4c819SXueming Li 	}
559328e105SMaxime Coquelin }
569328e105SMaxime Coquelin 
579328e105SMaxime Coquelin void
virtio_reinit_complete(struct virtio_hw * hw)589328e105SMaxime Coquelin virtio_reinit_complete(struct virtio_hw *hw)
599328e105SMaxime Coquelin {
609328e105SMaxime Coquelin 	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
619328e105SMaxime Coquelin }
629328e105SMaxime Coquelin 
639328e105SMaxime Coquelin void
virtio_set_status(struct virtio_hw * hw,uint8_t status)649328e105SMaxime Coquelin virtio_set_status(struct virtio_hw *hw, uint8_t status)
659328e105SMaxime Coquelin {
669328e105SMaxime Coquelin 	if (status != VIRTIO_CONFIG_STATUS_RESET)
679328e105SMaxime Coquelin 		status |= VIRTIO_OPS(hw)->get_status(hw);
689328e105SMaxime Coquelin 
699328e105SMaxime Coquelin 	VIRTIO_OPS(hw)->set_status(hw, status);
709328e105SMaxime Coquelin }
719328e105SMaxime Coquelin 
729328e105SMaxime Coquelin uint8_t
virtio_get_status(struct virtio_hw * hw)739328e105SMaxime Coquelin virtio_get_status(struct virtio_hw *hw)
749328e105SMaxime Coquelin {
759328e105SMaxime Coquelin 	return VIRTIO_OPS(hw)->get_status(hw);
769328e105SMaxime Coquelin }
776a504290SMaxime Coquelin 
786a504290SMaxime Coquelin uint8_t
virtio_get_isr(struct virtio_hw * hw)796a504290SMaxime Coquelin virtio_get_isr(struct virtio_hw *hw)
806a504290SMaxime Coquelin {
816a504290SMaxime Coquelin 	return VIRTIO_OPS(hw)->get_isr(hw);
826a504290SMaxime Coquelin }
83