xref: /dpdk/drivers/net/virtio/virtio.c (revision f5d4c819376b9a59e0f272e366fef0cd1fe9e4f2)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  * Copyright(c) 2020 Red Hat, Inc.
4  */
5 
6 #include <unistd.h>
7 
8 #include "virtio.h"
9 #include "virtio_logs.h"
10 
11 uint64_t
virtio_negotiate_features(struct virtio_hw * hw,uint64_t host_features)12 virtio_negotiate_features(struct virtio_hw *hw, uint64_t host_features)
13 {
14 	uint64_t features;
15 
16 	/*
17 	 * Limit negotiated features to what the driver, virtqueue, and
18 	 * host all support.
19 	 */
20 	features = host_features & hw->guest_features;
21 	VIRTIO_OPS(hw)->set_features(hw, features);
22 
23 	return features;
24 }
25 
26 
27 void
virtio_read_dev_config(struct virtio_hw * hw,size_t offset,void * dst,int length)28 virtio_read_dev_config(struct virtio_hw *hw, size_t offset,
29 		      void *dst, int length)
30 {
31 	VIRTIO_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
32 }
33 
34 void
virtio_write_dev_config(struct virtio_hw * hw,size_t offset,const void * src,int length)35 virtio_write_dev_config(struct virtio_hw *hw, size_t offset,
36 		       const void *src, int length)
37 {
38 	VIRTIO_OPS(hw)->write_dev_cfg(hw, offset, src, length);
39 }
40 
41 void
virtio_reset(struct virtio_hw * hw)42 virtio_reset(struct virtio_hw *hw)
43 {
44 	uint32_t retry = 0;
45 
46 	VIRTIO_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
47 	/* Flush status write and wait device ready max 3 seconds. */
48 	while (VIRTIO_OPS(hw)->get_status(hw) != VIRTIO_CONFIG_STATUS_RESET) {
49 		if (retry++ > 3000) {
50 			PMD_INIT_LOG(WARNING, "port %u device reset timeout", hw->port_id);
51 			break;
52 		}
53 		usleep(1000L);
54 	}
55 }
56 
57 void
virtio_reinit_complete(struct virtio_hw * hw)58 virtio_reinit_complete(struct virtio_hw *hw)
59 {
60 	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
61 }
62 
63 void
virtio_set_status(struct virtio_hw * hw,uint8_t status)64 virtio_set_status(struct virtio_hw *hw, uint8_t status)
65 {
66 	if (status != VIRTIO_CONFIG_STATUS_RESET)
67 		status |= VIRTIO_OPS(hw)->get_status(hw);
68 
69 	VIRTIO_OPS(hw)->set_status(hw, status);
70 }
71 
72 uint8_t
virtio_get_status(struct virtio_hw * hw)73 virtio_get_status(struct virtio_hw *hw)
74 {
75 	return VIRTIO_OPS(hw)->get_status(hw);
76 }
77 
78 uint8_t
virtio_get_isr(struct virtio_hw * hw)79 virtio_get_isr(struct virtio_hw *hw)
80 {
81 	return VIRTIO_OPS(hw)->get_isr(hw);
82 }
83