linux/drivers/thunderbolt/nhi.h
<<
>>
Prefs
   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
 115