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