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