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/thread_annotations.h>
21 #include <zircon/types.h>
22 
23 namespace virtio {
24 
25 class EthernetDevice : public Device {
26 public:
27     explicit EthernetDevice(zx_device_t* device, zx::bti, fbl::unique_ptr<Backend> backend);
28     virtual ~EthernetDevice();
29 
30     zx_status_t Init() override TA_EXCL(state_lock_);
31     void Release() override TA_EXCL(state_lock_);
32 
33     // VirtIO callbacks
34     void IrqRingUpdate() override TA_EXCL(state_lock_);
35     void IrqConfigChange() override TA_EXCL(state_lock_);
36 
37     // DDK protocol hooks; see ddk/protocol/ethernet.h
38     zx_status_t Query(uint32_t options, ethmac_info_t* info) TA_EXCL(state_lock_);
39     void Stop() TA_EXCL(state_lock_);
40     zx_status_t Start(const ethmac_ifc_t* ifc) TA_EXCL(state_lock_);
41     zx_status_t QueueTx(uint32_t options, ethmac_netbuf_t* netbuf) TA_EXCL(state_lock_);
42 
tag()43     const char* tag() const override { return "virtio-net"; }
44 
45 private:
46     DISALLOW_COPY_ASSIGN_AND_MOVE(EthernetDevice);
47 
48     // DDK device hooks; see ddk/device.h
49     void ReleaseLocked() TA_REQ(state_lock_);
50 
51     // Mutexes to control concurrent access
52     mtx_t state_lock_;
53     mtx_t tx_lock_;
54 
55     // Virtqueues; see section 5.1.2 of the spec
56     // This driver doesn't currently support multi-queueing, automatic
57     // steering, or the control virtqueue, so only a single queue is needed in
58     // each direction.
59     Ring rx_;
60     Ring tx_;
61     fbl::unique_ptr<io_buffer_t[]> bufs_;
62     size_t unkicked_ TA_GUARDED(tx_lock_);
63 
64     // Saved net device configuration out of the pci config BAR
65     virtio_net_config_t config_ TA_GUARDED(state_lock_);
66     size_t virtio_hdr_len_;
67 
68     // Ethmac callback interface; see ddk/protocol/ethernet.h
69     ethmac_ifc_t ifc_ TA_GUARDED(state_lock_);
70 };
71 
72 } // namespace virtio
73