1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#pragma once
6
7#include "device.h"
8#include "ring.h"
9
10#include <stddef.h>
11#include <stdint.h>
12#include <stdlib.h>
13
14#include <ddk/io-buffer.h>
15#include <ddk/protocol/ethernet.h>
16#include <fbl/macros.h>
17#include <fbl/unique_ptr.h>
18#include <virtio/net.h>
19#include <zircon/compiler.h>
20#include <zircon/device/ethernet.h>
21#include <zircon/thread_annotations.h>
22#include <zircon/types.h>
23
24namespace virtio {
25
26class EthernetDevice : public Device {
27public:
28    explicit EthernetDevice(zx_device_t* device, zx::bti, fbl::unique_ptr<Backend> backend);
29    virtual ~EthernetDevice();
30
31    zx_status_t Init() override TA_EXCL(state_lock_);
32    void Release() override TA_EXCL(state_lock_);
33
34    // VirtIO callbacks
35    void IrqRingUpdate() override TA_EXCL(state_lock_);
36    void IrqConfigChange() override TA_EXCL(state_lock_);
37
38    // DDK protocol hooks; see ddk/protocol/ethernet.h
39    zx_status_t Query(uint32_t options, ethmac_info_t* info) TA_EXCL(state_lock_);
40    void Stop() TA_EXCL(state_lock_);
41    zx_status_t Start(ethmac_ifc_t* ifc, void* cookie) TA_EXCL(state_lock_);
42    zx_status_t QueueTx(uint32_t options, ethmac_netbuf_t* netbuf) TA_EXCL(state_lock_);
43
44    const char* tag() const override { return "virtio-net"; }
45
46private:
47    DISALLOW_COPY_ASSIGN_AND_MOVE(EthernetDevice);
48
49    // DDK device hooks; see ddk/device.h
50    void ReleaseLocked() TA_REQ(state_lock_);
51
52    // Mutexes to control concurrent access
53    mtx_t state_lock_;
54    mtx_t tx_lock_;
55
56    // Virtqueues; see section 5.1.2 of the spec
57    // This driver doesn't currently support multi-queueing, automatic
58    // steering, or the control virtqueue, so only a single queue is needed in
59    // each direction.
60    Ring rx_;
61    Ring tx_;
62    fbl::unique_ptr<io_buffer_t[]> bufs_;
63    size_t unkicked_ TA_GUARDED(tx_lock_);
64
65    // Saved net device configuration out of the pci config BAR
66    virtio_net_config_t config_ TA_GUARDED(state_lock_);
67    size_t virtio_hdr_len_;
68
69    // Ethmac callback interface; see ddk/protocol/ethernet.h
70    ethmac_ifc_t* ifc_ TA_GUARDED(state_lock_);
71    void* cookie_;
72};
73
74} // namespace virtio
75