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 <ddk/device.h>
8#include <ddk/protocol/test.h>
9#include <ddktl/device.h>
10#include <ddktl/protocol/ethernet.h>
11#include <ddktl/protocol/test.h>
12#include <zircon/compiler.h>
13#include <zircon/types.h>
14#include <zircon/device/ethertap.h>
15#include <lib/zx/socket.h>
16#include <fbl/mutex.h>
17#include <fbl/unique_ptr.h>
18#include <threads.h>
19
20namespace eth {
21
22class TapCtl : public ddk::Device<TapCtl, ddk::Ioctlable> {
23  public:
24    TapCtl(zx_device_t* device);
25
26    void DdkRelease();
27    zx_status_t DdkIoctl(uint32_t op, const void* in_buf, size_t in_len, void* out_buf,
28                         size_t out_len, size_t* out_actual);
29};
30
31class TapDevice : public ddk::Device<TapDevice, ddk::Unbindable>,
32                  public ddk::EthmacProtocol<TapDevice> {
33  public:
34    TapDevice(zx_device_t* device, const ethertap_ioctl_config* config, zx::socket data);
35
36    void DdkRelease();
37    void DdkUnbind();
38
39    zx_status_t EthmacQuery(uint32_t options, ethmac_info_t* info);
40    void EthmacStop();
41    zx_status_t EthmacStart(fbl::unique_ptr<ddk::EthmacIfcProxy> proxy);
42    zx_status_t EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf);
43    zx_status_t EthmacSetParam(uint32_t param, int32_t value, void* data);
44    // No DMA capability, so return invalid handle for get_bti
45    zx_handle_t EthmacGetBti();
46    int Thread();
47
48  private:
49    zx_status_t UpdateLinkStatus(zx_signals_t observed);
50    zx_status_t Recv(uint8_t* buffer, uint32_t capacity);
51
52    // ethertap options
53    uint32_t options_ = 0;
54
55    // ethermac fields
56    uint32_t features_ = 0;
57    uint32_t mtu_ = 0;
58    uint8_t mac_[6] = {};
59
60    fbl::Mutex lock_;
61    bool dead_ = false;
62    fbl::unique_ptr<ddk::EthmacIfcProxy> ethmac_proxy_ __TA_GUARDED(lock_);
63
64    // Only accessed from Thread, so not locked.
65    bool online_ = false;
66    zx::socket data_;
67
68    thrd_t thread_;
69};
70
71}  // namespace eth
72