blob: f464584f5544158c8702d0dfaf5faf625d634b2d [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// WARNING: This file is machine generated by fidlc.
#pragma once
#include <ddk/protocol/ethernet.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/listnode.h>
#include <zircon/types.h>
#include "ethernet-internal.h"
// DDK ethmac-protocol support
//
// :: Proxies ::
//
// ddk::EthmacProtocolProxy is a simple wrapper around
// ethmac_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
// ddk::EthmacProtocol is a mixin class that simplifies writing DDK drivers
// that implement the ethmac protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_ETHMAC device.
// class EthmacDevice {
// using EthmacDeviceType = ddk::Device<EthmacDevice, /* ddk mixins */>;
//
// class EthmacDevice : public EthmacDeviceType,
// public ddk::EthmacProtocol<EthmacDevice> {
// public:
// EthmacDevice(zx_device_t* parent)
// : EthmacDeviceType("my-ethmac-protocol-device", parent) {}
//
// zx_status_t EthmacQuery(uint32_t options, ethmac_info_t* out_info);
//
// void EthmacStop();
//
// zx_status_t EthmacStart(const ethmac_ifc_t* ifc);
//
// zx_status_t EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf);
//
// zx_status_t EthmacSetParam(uint32_t param, zx_status_t value, const void* data_buffer, size_t
// data_size);
//
// zx_handle_t EthmacGetBti();
//
// ...
// };
namespace ddk {
template <typename D>
class EthmacIfc : public internal::base_mixin {
public:
EthmacIfc() {
internal::CheckEthmacIfcSubclass<D>();
ethmac_ifc_ops_.status = EthmacIfcStatus;
ethmac_ifc_ops_.recv = EthmacIfcRecv;
ethmac_ifc_ops_.complete_tx = EthmacIfcCompleteTx;
}
protected:
ethmac_ifc_ops_t ethmac_ifc_ops_ = {};
private:
static void EthmacIfcStatus(void* ctx, uint32_t status) {
static_cast<D*>(ctx)->EthmacIfcStatus(status);
}
static void EthmacIfcRecv(void* ctx, const void* data_buffer, size_t data_size,
uint32_t flags) {
static_cast<D*>(ctx)->EthmacIfcRecv(data_buffer, data_size, flags);
}
// complete_tx() is called to return ownership of a netbuf to the generic ethernet driver.
// Return status indicates queue state:
// ZX_OK: Packet has been enqueued.
// Other: Packet could not be enqueued.
// Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
// the completion state of the transmission itself.
static void EthmacIfcCompleteTx(void* ctx, ethmac_netbuf_t* netbuf, zx_status_t status) {
static_cast<D*>(ctx)->EthmacIfcCompleteTx(netbuf, status);
}
};
class EthmacIfcProxy {
public:
EthmacIfcProxy() : ops_(nullptr), ctx_(nullptr) {}
EthmacIfcProxy(const ethmac_ifc_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(ethmac_ifc_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
bool is_valid() { return ops_ != nullptr; }
void clear() {
ctx_ = nullptr;
ops_ = nullptr;
}
void Status(uint32_t status) { ops_->status(ctx_, status); }
void Recv(const void* data_buffer, size_t data_size, uint32_t flags) {
ops_->recv(ctx_, data_buffer, data_size, flags);
}
// complete_tx() is called to return ownership of a netbuf to the generic ethernet driver.
// Return status indicates queue state:
// ZX_OK: Packet has been enqueued.
// Other: Packet could not be enqueued.
// Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
// the completion state of the transmission itself.
void CompleteTx(ethmac_netbuf_t* netbuf, zx_status_t status) {
ops_->complete_tx(ctx_, netbuf, status);
}
private:
ethmac_ifc_ops_t* ops_;
void* ctx_;
};
// The ethernet midlayer will never call ethermac_protocol
// methods from multiple threads simultaneously, but it
// can call send() methods at the same time as non-send
// methods.
template <typename D>
class EthmacProtocol : public internal::base_mixin {
public:
EthmacProtocol() {
internal::CheckEthmacProtocolSubclass<D>();
ethmac_protocol_ops_.query = EthmacQuery;
ethmac_protocol_ops_.stop = EthmacStop;
ethmac_protocol_ops_.start = EthmacStart;
ethmac_protocol_ops_.queue_tx = EthmacQueueTx;
ethmac_protocol_ops_.set_param = EthmacSetParam;
ethmac_protocol_ops_.get_bti = EthmacGetBti;
}
protected:
ethmac_protocol_ops_t ethmac_protocol_ops_ = {};
private:
// Obtain information about the ethermac device and supported features
// Safe to call at any time.
static zx_status_t EthmacQuery(void* ctx, uint32_t options, ethmac_info_t* out_info) {
return static_cast<D*>(ctx)->EthmacQuery(options, out_info);
}
// Shut down a running ethermac
// Safe to call if the ethermac is already stopped.
static void EthmacStop(void* ctx) { static_cast<D*>(ctx)->EthmacStop(); }
// Start ethermac running with ifc_virt
// Callbacks on ifc may be invoked from now until stop() is called
static zx_status_t EthmacStart(void* ctx, const ethmac_ifc_t* ifc) {
return static_cast<D*>(ctx)->EthmacStart(ifc);
}
// Request transmission of the packet in netbuf. Return status indicates queue state:
// ZX_ERR_SHOULD_WAIT: Packet is being enqueued.
// ZX_OK: Packet has been enqueued.
// Other: Packet could not be enqueued.
// In the SHOULD_WAIT case the driver takes ownership of the netbuf and must call complete_tx()
// to return it once the enqueue is complete. complete_tx() may be used to return the packet
// before transmission itself completes, but MUST NOT be called from within the queue_tx()
// implementation.
// queue_tx() may be called at any time after start() is called including from multiple threads
// simultaneously.
static zx_status_t EthmacQueueTx(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf) {
return static_cast<D*>(ctx)->EthmacQueueTx(options, netbuf);
}
// Request a settings change for the driver. Return status indicates disposition:
// ZX_OK: Request has been handled.
// ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
// Other: Error trying to support this request.
// |value| and |data| usage are defined for each |param|; see comments above.
// set_param() may be called at any time after start() is called including from multiple threads
// simultaneously.
static zx_status_t EthmacSetParam(void* ctx, uint32_t param, zx_status_t value,
const void* data_buffer, size_t data_size) {
return static_cast<D*>(ctx)->EthmacSetParam(param, value, data_buffer, data_size);
}
// Get the BTI handle (needed to pin DMA memory) for this device.
// This method is only valid on devices that advertise ETHMAC_FEATURE_DMA
// The caller does *not* take ownership of the BTI handle and must never close
// the handle.
static zx_handle_t EthmacGetBti(void* ctx) { return static_cast<D*>(ctx)->EthmacGetBti(); }
};
class EthmacProtocolProxy {
public:
EthmacProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
EthmacProtocolProxy(const ethmac_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(ethmac_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
bool is_valid() { return ops_ != nullptr; }
void clear() {
ctx_ = nullptr;
ops_ = nullptr;
}
// Obtain information about the ethermac device and supported features
// Safe to call at any time.
zx_status_t Query(uint32_t options, ethmac_info_t* out_info) {
return ops_->query(ctx_, options, out_info);
}
// Shut down a running ethermac
// Safe to call if the ethermac is already stopped.
void Stop() { ops_->stop(ctx_); }
// Start ethermac running with ifc_virt
// Callbacks on ifc may be invoked from now until stop() is called
zx_status_t Start(const ethmac_ifc_t* ifc) { return ops_->start(ctx_, ifc); }
// Request transmission of the packet in netbuf. Return status indicates queue state:
// ZX_ERR_SHOULD_WAIT: Packet is being enqueued.
// ZX_OK: Packet has been enqueued.
// Other: Packet could not be enqueued.
// In the SHOULD_WAIT case the driver takes ownership of the netbuf and must call complete_tx()
// to return it once the enqueue is complete. complete_tx() may be used to return the packet
// before transmission itself completes, but MUST NOT be called from within the queue_tx()
// implementation.
// queue_tx() may be called at any time after start() is called including from multiple threads
// simultaneously.
zx_status_t QueueTx(uint32_t options, ethmac_netbuf_t* netbuf) {
return ops_->queue_tx(ctx_, options, netbuf);
}
// Request a settings change for the driver. Return status indicates disposition:
// ZX_OK: Request has been handled.
// ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
// Other: Error trying to support this request.
// |value| and |data| usage are defined for each |param|; see comments above.
// set_param() may be called at any time after start() is called including from multiple threads
// simultaneously.
zx_status_t SetParam(uint32_t param, zx_status_t value, const void* data_buffer,
size_t data_size) {
return ops_->set_param(ctx_, param, value, data_buffer, data_size);
}
// Get the BTI handle (needed to pin DMA memory) for this device.
// This method is only valid on devices that advertise ETHMAC_FEATURE_DMA
// The caller does *not* take ownership of the BTI handle and must never close
// the handle.
zx_handle_t GetBti() { return ops_->get_bti(ctx_); }
private:
ethmac_protocol_ops_t* ops_;
void* ctx_;
};
} // namespace ddk