/* $NetBSD: ldcvar.h,v 1.1 2016/08/19 19:02:07 palle Exp $ */
/* $OpenBSD: ldcvar.h,v 1.6 2014/09/29 17:43:29 kettenis Exp $ */
/*
* Copyright (c) 2009 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* LDC queues.
*/
#include <sys/mutex.h>
struct ldc_queue {
kmutex_t lq_mtx;
#if OPENBSD_BUSDMA
bus_dmamap_t lq_map;
bus_dma_segment_t lq_seg;
#endif
vaddr_t lq_va;
int lq_nentries;
};
#if OPENBSD_BUSDMA
struct ldc_queue *ldc_queue_alloc(bus_dma_tag_t, int);
void ldc_queue_free(bus_dma_tag_t, struct ldc_queue *);
#else
struct ldc_queue *ldc_queue_alloc(int);
void ldc_queue_free(struct ldc_queue *);
#endif
/*
* LDC virtual link layer protocol.
*/
#define LDC_VERSION_MAJOR 1
#define LDC_VERSION_MINOR 0
#define LDC_PKT_PAYLOAD 56
struct ldc_pkt {
uint8_t type;
uint8_t stype;
uint8_t ctrl;
uint8_t env;
uint32_t seqid;
uint16_t major;
uint16_t minor;
uint32_t _reserved[13];
};
/* Packet types. */
#define LDC_CTRL 0x01
#define LDC_DATA 0x02
#define LDC_ERR 0x10
/* Packet subtypes. */
#define LDC_INFO 0x01
#define LDC_ACK 0x02
#define LDC_NACK 0x04
/* Control info values. */
#define LDC_VERS 0x01
#define LDC_RTS 0x02
#define LDC_RTR 0x03
#define LDC_RDX 0x04
/* Packet envelope. */
#define LDC_MODE_RAW 0x00
#define LDC_MODE_UNRELIABLE 0x01
#define LDC_MODE_RELIABLE 0x03
#define LDC_LEN_MASK 0x3f
#define LDC_FRAG_MASK 0xc0
#define LDC_FRAG_START 0x40
#define LDC_FRAG_STOP 0x80
/*
* XXX Get rid of the +8 once we no longer need to store the header of
* the first packet.
*/
#define LDC_MSG_MAX (128 + 8)
struct ldc_conn {
uint64_t lc_id;
struct ldc_queue *lc_txq;
struct ldc_queue *lc_rxq;
uint64_t lc_tx_state;
uint64_t lc_rx_state;
uint32_t lc_tx_seqid;
uint8_t lc_state;
#define LDC_SND_VERS 1
#define LDC_RCV_VERS 2
#define LDC_SND_RTS 3
#define LDC_SND_RTR 4
#define LDC_SND_RDX 5
uint64_t lc_msg[LDC_MSG_MAX / 8];
size_t lc_len;
void *lc_sc;
void (*lc_reset)(struct ldc_conn *);
void (*lc_start)(struct ldc_conn *);
void (*lc_rx_data)(struct ldc_conn *, struct ldc_pkt *);
};
void ldc_rx_ctrl(struct ldc_conn *, struct ldc_pkt *);
void ldc_rx_data(struct ldc_conn *, struct ldc_pkt *);
void ldc_send_vers(struct ldc_conn *);
int ldc_send_unreliable(struct ldc_conn *, void *, size_t);
void ldc_reset(struct ldc_conn *);
/*
* LDC map tables.
*/
struct ldc_map_slot {
uint64_t entry;
uint64_t cookie;
};
#define LDC_MTE_R 0x0000000000000010ULL
#define LDC_MTE_W 0x0000000000000020ULL
#define LDC_MTE_X 0x0000000000000040ULL
#define LDC_MTE_IOR 0x0000000000000080ULL
#define LDC_MTE_IOW 0x0000000000000100ULL
#define LDC_MTE_CPR 0x0000000000000200ULL
#define LDC_MTE_CPW 0x0000000000000400ULL
#define LDC_MTE_RA_MASK 0x007fffffffffe000ULL
struct ldc_map {
#if OPENBSD_BUSDMA
bus_dmamap_t lm_map;
bus_dma_segment_t lm_seg;
#endif
struct ldc_map_slot *lm_slot;
int lm_nentries;
int lm_next;
int lm_count;
};
#if OPENBSD_BUSDMA
struct ldc_map *ldc_map_alloc(bus_dma_tag_t, int);
void ldc_map_free(bus_dma_tag_t, struct ldc_map *);
#else
struct ldc_map *ldc_map_alloc(int);
void ldc_map_free(struct ldc_map *);
#endif
struct ldc_cookie {
uint64_t addr;
uint64_t size;
};