Linux Audio

Check our new training course

Linux kernel drivers training

May 6-19, 2025
Register
Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Thunderbolt Cactus Ridge driver - NHI driver
  3 *
  4 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
  5 */
  6
  7#ifndef DSL3510_H_
  8#define DSL3510_H_
  9
 10#include <linux/mutex.h>
 11#include <linux/workqueue.h>
 12
 13/**
 14 * struct tb_nhi - thunderbolt native host interface
 15 */
 16struct tb_nhi {
 17	struct mutex lock; /*
 18			    * Must be held during ring creation/destruction.
 19			    * Is acquired by interrupt_work when dispatching
 20			    * interrupts to individual rings.
 21			    **/
 22	struct pci_dev *pdev;
 23	void __iomem *iobase;
 24	struct tb_ring **tx_rings;
 25	struct tb_ring **rx_rings;
 26	struct work_struct interrupt_work;
 27	u32 hop_count; /* Number of rings (end point hops) supported by NHI. */
 28};
 29
 30/**
 31 * struct tb_ring - thunderbolt TX or RX ring associated with a NHI
 32 */
 33struct tb_ring {
 34	struct mutex lock; /* must be acquired after nhi->lock */
 35	struct tb_nhi *nhi;
 36	int size;
 37	int hop;
 38	int head; /* write next descriptor here */
 39	int tail; /* complete next descriptor here */
 40	struct ring_desc *descriptors;
 41	dma_addr_t descriptors_dma;
 42	struct list_head queue;
 43	struct list_head in_flight;
 44	struct work_struct work;
 45	bool is_tx:1; /* rx otherwise */
 46	bool running:1;
 47};
 48
 49struct ring_frame;
 50typedef void (*ring_cb)(struct tb_ring*, struct ring_frame*, bool canceled);
 51
 52/**
 53 * struct ring_frame - for use with ring_rx/ring_tx
 54 */
 55struct ring_frame {
 56	dma_addr_t buffer_phy;
 57	ring_cb callback;
 58	struct list_head list;
 59	u32 size:12; /* TX: in, RX: out*/
 60	u32 flags:12; /* RX: out */
 61	u32 eof:4; /* TX:in, RX: out */
 62	u32 sof:4; /* TX:in, RX: out */
 63};
 64
 65#define TB_FRAME_SIZE 0x100    /* minimum size for ring_rx */
 66
 67struct tb_ring *ring_alloc_tx(struct tb_nhi *nhi, int hop, int size);
 68struct tb_ring *ring_alloc_rx(struct tb_nhi *nhi, int hop, int size);
 69void ring_start(struct tb_ring *ring);
 70void ring_stop(struct tb_ring *ring);
 71void ring_free(struct tb_ring *ring);
 72
 73int __ring_enqueue(struct tb_ring *ring, struct ring_frame *frame);
 74
 75/**
 76 * ring_rx() - enqueue a frame on an RX ring
 77 *
 78 * frame->buffer, frame->buffer_phy and frame->callback have to be set. The
 79 * buffer must contain at least TB_FRAME_SIZE bytes.
 80 *
 81 * frame->callback will be invoked with frame->size, frame->flags, frame->eof,
 82 * frame->sof set once the frame has been received.
 83 *
 84 * If ring_stop is called after the packet has been enqueued frame->callback
 85 * will be called with canceled set to true.
 86 *
 87 * Return: Returns ESHUTDOWN if ring_stop has been called. Zero otherwise.
 88 */
 89static inline int ring_rx(struct tb_ring *ring, struct ring_frame *frame)
 90{
 91	WARN_ON(ring->is_tx);
 92	return __ring_enqueue(ring, frame);
 93}
 94
 95/**
 96 * ring_tx() - enqueue a frame on an TX ring
 97 *
 98 * frame->buffer, frame->buffer_phy, frame->callback, frame->size, frame->eof
 99 * and frame->sof have to be set.
100 *
101 * frame->callback will be invoked with once the frame has been transmitted.
102 *
103 * If ring_stop is called after the packet has been enqueued frame->callback
104 * will be called with canceled set to true.
105 *
106 * Return: Returns ESHUTDOWN if ring_stop has been called. Zero otherwise.
107 */
108static inline int ring_tx(struct tb_ring *ring, struct ring_frame *frame)
109{
110	WARN_ON(!ring->is_tx);
111	return __ring_enqueue(ring, frame);
112}
113
114#endif