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 */ 16 struct 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 */ 33 struct 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 49 struct ring_frame; 50 typedef 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 */ 55 struct 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 67 struct tb_ring *ring_alloc_tx(struct tb_nhi *nhi, int hop, int size); 68 struct tb_ring *ring_alloc_rx(struct tb_nhi *nhi, int hop, int size); 69 void ring_start(struct tb_ring *ring); 70 void ring_stop(struct tb_ring *ring); 71 void ring_free(struct tb_ring *ring); 72 73 int __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 */ 89 static 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 */ 108 static 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 115