blob: 7b740a959bc8f76c20d77aa75c300d4091b78397 [file] [log] [blame]
// Copyright 2017 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.
#pragma once
#include <stdint.h>
#include <zircon/device/ioctl-wrapper.h>
#include <zircon/device/ioctl.h>
#include <zircon/types.h>
// TODO: GET_DEVICE_INFO ioctl
// Get the 6 byte ethernet device MAC address
// in: none
// out: eth_info_t*
#define IOCTL_ETHERNET_GET_INFO \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 0)
typedef struct eth_info_t {
uint32_t features;
uint32_t mtu;
uint8_t mac[6];
uint8_t pad[2];
uint32_t reserved[12];
} eth_info_t;
#define ETH_SIGNAL_STATUS ZX_USER_SIGNAL_0
// Ethernet device features
// Device is a wireless network device
#define ETH_FEATURE_WLAN 1
// Device is a synthetic network device
#define ETH_FEATURE_SYNTH 2
// Get the fifos to submit tx and rx operations
// in: none
// out: eth_fifos_t*
#define IOCTL_ETHERNET_GET_FIFOS \
IOCTL(IOCTL_KIND_GET_TWO_HANDLES, IOCTL_FAMILY_ETH, 1)
typedef struct eth_fifos_t {
// handles to tx and rx fifos
zx_handle_t tx_fifo;
zx_handle_t rx_fifo;
// maximum number of items in fifos
uint32_t tx_depth;
uint32_t rx_depth;
} eth_fifos_t;
// Set the io buffer that tx and rx operations act on
// in: zx_handle_t (vmo)
// out: none
#define IOCTL_ETHERNET_SET_IOBUF \
IOCTL(IOCTL_KIND_SET_HANDLE, IOCTL_FAMILY_ETH, 2)
// Start/Stop transferring packets
// Start will not succeed (ZX_ERR_BAD_STATE) until the fifos have been
// obtained and an io buffer vmo has been registered.
#define IOCTL_ETHERNET_START \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 3)
#define IOCTL_ETHERNET_STOP \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 4)
// Receive all TX packets on this device looped back on RX path
#define IOCTL_ETHERNET_TX_LISTEN_START \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 5)
#define IOCTL_ETHERNET_TX_LISTEN_STOP \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 6)
// Associates a name with an ethernet instance.
#define IOCTL_ETHERNET_SET_CLIENT_NAME \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 7)
// Returns: uint32_t link_status_bits
// The signal ETH_SIGNAL_STATUS will be asserted on rx_fifo when these bits change, and
// de-asserted when this ioctl is called.
#define IOCTL_ETHERNET_GET_STATUS \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 8)
// Start/Stop promiscuous mode
// in: bool
#define IOCTL_ETHERNET_SET_PROMISC \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 9)
// Configure multicast mode
// in: eth_multicast_config_t*
// out: none
#define IOCTL_ETHERNET_CONFIG_MULTICAST \
IOCTL(IOCTL_KIND_DEFAULT, IOCTL_FAMILY_ETH, 10)
// If multicast promiscuous is not on, the filter will be used. Filter config is remembered and
// can be updated while promiscuous is on. Address must be multicast (LSb of MSB is 1)
#define ETH_MULTICAST_ADD_MAC 0
#define ETH_MULTICAST_DEL_MAC 1
#define ETH_MULTICAST_RECV_ALL 2
#define ETH_MULTICAST_RECV_FILTER 3
// TEST_FILTER turns off multicast promisc regardless of other ethdev's requests.
// Use only during testing!
#define ETH_MULTICAST_TEST_FILTER 4
#define ETH_MULTICAST_DUMP_REGS 5
typedef struct eth_multicast_config_t {
uint32_t op; // one of ETH_MULTICAST_ #defines
uint8_t mac[6]; // used in ADD_MAC and DEL_MAC
} eth_multicast_config_t;
// Link status bits:
#define ETH_STATUS_ONLINE (1u)
// Operation
//
// Packets are transmitted by writing data into the io_vmo and writing
// an eth_fifo_entry_t referencing that data (offset + length) into the
// tx_fifo. When the driver is done accessing the data, an eth_fifo_entry_t
// with the same cookie value (opaque to the driver) will be readable
// from the tx fifo.
//
// Packets are received by writing an eth_fifo_entry_t referencing an
// available buffer (offset + length) in the io_vmo. When a packet is
// received, an eth_fifo_entry_t with the same cookie value (opaque to
// the driver) will be readable from the rx fifo. The offset field will
// be the same as was sent. The length field will reflect the actual size
// of the received packet. The flags field will indicate success or a
// specific failure condition.
//
// IMPORTANT: The driver *will not* buffer response messages. It is the
// client's responsibility to ensure that there is space in the reply side
// of each fifo for each outstanding tx or rx request. The fifo sizes
// are returned along with the fifo handles in the eth_fifos_t.
// flags values for request messages
// - none -
// flags values for response messages
#define ETH_FIFO_RX_OK (1u) // packet received okay
#define ETH_FIFO_TX_OK (1u) // packet transmitted okay
#define ETH_FIFO_INVALID (2u) // offset+length not within io_vmo bounds
#define ETH_FIFO_RX_TX (4u) // received our own tx packet (when TX_LISTEN)
typedef struct eth_fifo_entry {
// offset from start of io_vmo to packet data
uint32_t offset;
// length of packet data
uint16_t length;
uint16_t flags;
// opaque cookie
void* cookie;
} eth_fifo_entry_t;
// ssize_t ioctl_ethernet_get_info(int fd, eth_info_t* out);
IOCTL_WRAPPER_OUT(ioctl_ethernet_get_info, IOCTL_ETHERNET_GET_INFO, eth_info_t);
// ssize_t ioctl_ethernet_get_fifos(int fd, eth_fifos_t* out);
IOCTL_WRAPPER_OUT(ioctl_ethernet_get_fifos, IOCTL_ETHERNET_GET_FIFOS, eth_fifos_t);
// ssize_t ioctl_ethernet_set_iobuf(int fd, zx_handle_t_t* entries);
IOCTL_WRAPPER_IN(ioctl_ethernet_set_iobuf, IOCTL_ETHERNET_SET_IOBUF, zx_handle_t);
// ssize_t ioctl_ethernet_start(int fd);
IOCTL_WRAPPER(ioctl_ethernet_start, IOCTL_ETHERNET_START);
// ssize_t ioctl_ethernet_stop(int fd);
IOCTL_WRAPPER(ioctl_ethernet_stop, IOCTL_ETHERNET_STOP);
// ssize_t ioctl_ethernet_tx_listen_start(int fd);
IOCTL_WRAPPER(ioctl_ethernet_tx_listen_start, IOCTL_ETHERNET_TX_LISTEN_START);
// ssize_t ioctl_ethernet_tx_listen_stop(int fd);
IOCTL_WRAPPER(ioctl_ethernet_tx_listen_stop, IOCTL_ETHERNET_TX_LISTEN_STOP);
// ssize_t ioctl_ethernet_set_client_name(int fd, const char* in, size_t in_len);
IOCTL_WRAPPER_VARIN(ioctl_ethernet_set_client_name, IOCTL_ETHERNET_SET_CLIENT_NAME, char);
// ssize_t ioctl_ethernet_get_status(int fd, uint32_t*);
IOCTL_WRAPPER_OUT(ioctl_ethernet_get_status, IOCTL_ETHERNET_GET_STATUS, uint32_t);
// ssize_t ioctl_ethernet_set_promisc(int fd, bool*);
IOCTL_WRAPPER_IN(ioctl_ethernet_set_promisc, IOCTL_ETHERNET_SET_PROMISC, bool);
// ssize_t ioctl_ethernet_config_multicast(int fd, const eth_multicast_config_t *);
IOCTL_WRAPPER_IN(ioctl_ethernet_config_multicast, IOCTL_ETHERNET_CONFIG_MULTICAST,
eth_multicast_config_t)