nhi.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Thunderbolt Cactus Ridge driver - NHI driver
  3. *
  4. * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
  5. */
  6. #ifndef DSL3510_H_
  7. #define DSL3510_H_
  8. #include <linux/idr.h>
  9. #include <linux/mutex.h>
  10. #include <linux/workqueue.h>
  11. /**
  12. * struct tb_nhi - thunderbolt native host interface
  13. * @lock: Must be held during ring creation/destruction. Is acquired by
  14. * interrupt_work when dispatching interrupts to individual rings.
  15. * @pdev: Pointer to the PCI device
  16. * @iobase: MMIO space of the NHI
  17. * @tx_rings: All Tx rings available on this host controller
  18. * @rx_rings: All Rx rings available on this host controller
  19. * @msix_ida: Used to allocate MSI-X vectors for rings
  20. * @going_away: The host controller device is about to disappear so when
  21. * this flag is set, avoid touching the hardware anymore.
  22. * @interrupt_work: Work scheduled to handle ring interrupt when no
  23. * MSI-X is used.
  24. * @hop_count: Number of rings (end point hops) supported by NHI.
  25. */
  26. struct tb_nhi {
  27. struct mutex lock;
  28. struct pci_dev *pdev;
  29. void __iomem *iobase;
  30. struct tb_ring **tx_rings;
  31. struct tb_ring **rx_rings;
  32. struct ida msix_ida;
  33. bool going_away;
  34. struct work_struct interrupt_work;
  35. u32 hop_count;
  36. };
  37. /**
  38. * struct tb_ring - thunderbolt TX or RX ring associated with a NHI
  39. * @lock: Lock serializing actions to this ring. Must be acquired after
  40. * nhi->lock.
  41. * @nhi: Pointer to the native host controller interface
  42. * @size: Size of the ring
  43. * @hop: Hop (DMA channel) associated with this ring
  44. * @head: Head of the ring (write next descriptor here)
  45. * @tail: Tail of the ring (complete next descriptor here)
  46. * @descriptors: Allocated descriptors for this ring
  47. * @queue: Queue holding frames to be transferred over this ring
  48. * @in_flight: Queue holding frames that are currently in flight
  49. * @work: Interrupt work structure
  50. * @is_tx: Is the ring Tx or Rx
  51. * @running: Is the ring running
  52. * @irq: MSI-X irq number if the ring uses MSI-X. %0 otherwise.
  53. * @vector: MSI-X vector number the ring uses (only set if @irq is > 0)
  54. * @flags: Ring specific flags
  55. */
  56. struct tb_ring {
  57. struct mutex lock;
  58. struct tb_nhi *nhi;
  59. int size;
  60. int hop;
  61. int head;
  62. int tail;
  63. struct ring_desc *descriptors;
  64. dma_addr_t descriptors_dma;
  65. struct list_head queue;
  66. struct list_head in_flight;
  67. struct work_struct work;
  68. bool is_tx:1;
  69. bool running:1;
  70. int irq;
  71. u8 vector;
  72. unsigned int flags;
  73. };
  74. /* Leave ring interrupt enabled on suspend */
  75. #define RING_FLAG_NO_SUSPEND BIT(0)
  76. struct ring_frame;
  77. typedef void (*ring_cb)(struct tb_ring*, struct ring_frame*, bool canceled);
  78. /**
  79. * struct ring_frame - for use with ring_rx/ring_tx
  80. */
  81. struct ring_frame {
  82. dma_addr_t buffer_phy;
  83. ring_cb callback;
  84. struct list_head list;
  85. u32 size:12; /* TX: in, RX: out*/
  86. u32 flags:12; /* RX: out */
  87. u32 eof:4; /* TX:in, RX: out */
  88. u32 sof:4; /* TX:in, RX: out */
  89. };
  90. #define TB_FRAME_SIZE 0x100 /* minimum size for ring_rx */
  91. struct tb_ring *ring_alloc_tx(struct tb_nhi *nhi, int hop, int size,
  92. unsigned int flags);
  93. struct tb_ring *ring_alloc_rx(struct tb_nhi *nhi, int hop, int size,
  94. unsigned int flags);
  95. void ring_start(struct tb_ring *ring);
  96. void ring_stop(struct tb_ring *ring);
  97. void ring_free(struct tb_ring *ring);
  98. int __ring_enqueue(struct tb_ring *ring, struct ring_frame *frame);
  99. /**
  100. * ring_rx() - enqueue a frame on an RX ring
  101. *
  102. * frame->buffer, frame->buffer_phy and frame->callback have to be set. The
  103. * buffer must contain at least TB_FRAME_SIZE bytes.
  104. *
  105. * frame->callback will be invoked with frame->size, frame->flags, frame->eof,
  106. * frame->sof set once the frame has been received.
  107. *
  108. * If ring_stop is called after the packet has been enqueued frame->callback
  109. * will be called with canceled set to true.
  110. *
  111. * Return: Returns ESHUTDOWN if ring_stop has been called. Zero otherwise.
  112. */
  113. static inline int ring_rx(struct tb_ring *ring, struct ring_frame *frame)
  114. {
  115. WARN_ON(ring->is_tx);
  116. return __ring_enqueue(ring, frame);
  117. }
  118. /**
  119. * ring_tx() - enqueue a frame on an TX ring
  120. *
  121. * frame->buffer, frame->buffer_phy, frame->callback, frame->size, frame->eof
  122. * and frame->sof have to be set.
  123. *
  124. * frame->callback will be invoked with once the frame has been transmitted.
  125. *
  126. * If ring_stop is called after the packet has been enqueued frame->callback
  127. * will be called with canceled set to true.
  128. *
  129. * Return: Returns ESHUTDOWN if ring_stop has been called. Zero otherwise.
  130. */
  131. static inline int ring_tx(struct tb_ring *ring, struct ring_frame *frame)
  132. {
  133. WARN_ON(!ring->is_tx);
  134. return __ring_enqueue(ring, frame);
  135. }
  136. enum nhi_fw_mode {
  137. NHI_FW_SAFE_MODE,
  138. NHI_FW_AUTH_MODE,
  139. NHI_FW_EP_MODE,
  140. NHI_FW_CM_MODE,
  141. };
  142. enum nhi_mailbox_cmd {
  143. NHI_MAILBOX_SAVE_DEVS = 0x05,
  144. NHI_MAILBOX_DISCONNECT_PCIE_PATHS = 0x06,
  145. NHI_MAILBOX_DRV_UNLOADS = 0x07,
  146. NHI_MAILBOX_ALLOW_ALL_DEVS = 0x23,
  147. };
  148. int nhi_mailbox_cmd(struct tb_nhi *nhi, enum nhi_mailbox_cmd cmd, u32 data);
  149. enum nhi_fw_mode nhi_mailbox_mode(struct tb_nhi *nhi);
  150. /*
  151. * PCI IDs used in this driver from Win Ridge forward. There is no
  152. * need for the PCI quirk anymore as we will use ICM also on Apple
  153. * hardware.
  154. */
  155. #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_NHI 0x157d
  156. #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_BRIDGE 0x157e
  157. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_NHI 0x15bf
  158. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE 0x15c0
  159. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI 0x15d2
  160. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE 0x15d3
  161. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI 0x15d9
  162. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE 0x15da
  163. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_USBONLY_NHI 0x15dc
  164. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_USBONLY_NHI 0x15dd
  165. #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI 0x15de
  166. #endif