hif.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. //------------------------------------------------------------------------------
  2. // <copyright file="hif.h" company="Atheros">
  3. // Copyright (c) 2004-2008 Atheros Corporation. All rights reserved.
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License version 2 as
  7. // published by the Free Software Foundation;
  8. //
  9. // Software distributed under the License is distributed on an "AS
  10. // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11. // implied. See the License for the specific language governing
  12. // rights and limitations under the License.
  13. //
  14. //
  15. //------------------------------------------------------------------------------
  16. //==============================================================================
  17. // HIF specific declarations and prototypes
  18. //
  19. // Author(s): ="Atheros"
  20. //==============================================================================
  21. #ifndef _HIF_H_
  22. #define _HIF_H_
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif /* __cplusplus */
  26. /* Header files */
  27. #include "a_config.h"
  28. #include "athdefs.h"
  29. #include "a_types.h"
  30. #include "a_osapi.h"
  31. #include "dl_list.h"
  32. typedef struct htc_callbacks HTC_CALLBACKS;
  33. typedef struct hif_device HIF_DEVICE;
  34. /*
  35. * direction - Direction of transfer (HIF_READ/HIF_WRITE).
  36. */
  37. #define HIF_READ 0x00000001
  38. #define HIF_WRITE 0x00000002
  39. #define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
  40. /*
  41. * type - An interface may support different kind of read/write commands.
  42. * For example: SDIO supports CMD52/CMD53s. In case of MSIO it
  43. * translates to using different kinds of TPCs. The command type
  44. * is thus divided into a basic and an extended command and can
  45. * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
  46. */
  47. #define HIF_BASIC_IO 0x00000004
  48. #define HIF_EXTENDED_IO 0x00000008
  49. #define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO)
  50. /*
  51. * emode - This indicates the whether the command is to be executed in a
  52. * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
  53. * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
  54. * implemented using the asynchronous mode allowing the the bus
  55. * driver to indicate the completion of operation through the
  56. * registered callback routine. The requirement primarily comes
  57. * from the contexts these operations get called from (a driver's
  58. * transmit context or the ISR context in case of receive).
  59. * Support for both of these modes is essential.
  60. */
  61. #define HIF_SYNCHRONOUS 0x00000010
  62. #define HIF_ASYNCHRONOUS 0x00000020
  63. #define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
  64. /*
  65. * dmode - An interface may support different kinds of commands based on
  66. * the tradeoff between the amount of data it can carry and the
  67. * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
  68. * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
  69. * to the nearest block size by padding. The size of the block is
  70. * configurable at compile time using the HIF_BLOCK_SIZE and is
  71. * negotiated with the target during initialization after the
  72. * AR6000 interrupts are enabled.
  73. */
  74. #define HIF_BYTE_BASIS 0x00000040
  75. #define HIF_BLOCK_BASIS 0x00000080
  76. #define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
  77. /*
  78. * amode - This indicates if the address has to be incremented on AR6000
  79. * after every read/write operation (HIF?FIXED_ADDRESS/
  80. * HIF_INCREMENTAL_ADDRESS).
  81. */
  82. #define HIF_FIXED_ADDRESS 0x00000100
  83. #define HIF_INCREMENTAL_ADDRESS 0x00000200
  84. #define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
  85. #define HIF_WR_ASYNC_BYTE_FIX \
  86. (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
  87. #define HIF_WR_ASYNC_BYTE_INC \
  88. (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
  89. #define HIF_WR_ASYNC_BLOCK_INC \
  90. (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
  91. #define HIF_WR_SYNC_BYTE_FIX \
  92. (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
  93. #define HIF_WR_SYNC_BYTE_INC \
  94. (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
  95. #define HIF_WR_SYNC_BLOCK_INC \
  96. (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
  97. #define HIF_WR_ASYNC_BLOCK_FIX \
  98. (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
  99. #define HIF_WR_SYNC_BLOCK_FIX \
  100. (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
  101. #define HIF_RD_SYNC_BYTE_INC \
  102. (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
  103. #define HIF_RD_SYNC_BYTE_FIX \
  104. (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
  105. #define HIF_RD_ASYNC_BYTE_FIX \
  106. (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
  107. #define HIF_RD_ASYNC_BLOCK_FIX \
  108. (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
  109. #define HIF_RD_ASYNC_BYTE_INC \
  110. (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
  111. #define HIF_RD_ASYNC_BLOCK_INC \
  112. (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
  113. #define HIF_RD_SYNC_BLOCK_INC \
  114. (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
  115. #define HIF_RD_SYNC_BLOCK_FIX \
  116. (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
  117. typedef enum {
  118. HIF_DEVICE_POWER_STATE = 0,
  119. HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
  120. HIF_DEVICE_GET_MBOX_ADDR,
  121. HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
  122. HIF_DEVICE_GET_IRQ_PROC_MODE,
  123. HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
  124. HIF_DEVICE_POWER_STATE_CHANGE,
  125. HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
  126. HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
  127. HIF_DEVICE_GET_OS_DEVICE,
  128. } HIF_DEVICE_CONFIG_OPCODE;
  129. /*
  130. * HIF CONFIGURE definitions:
  131. *
  132. * HIF_DEVICE_GET_MBOX_BLOCK_SIZE
  133. * input : none
  134. * output : array of 4 A_UINT32s
  135. * notes: block size is returned for each mailbox (4)
  136. *
  137. * HIF_DEVICE_GET_MBOX_ADDR
  138. * input : none
  139. * output : array of 4 A_UINT32
  140. * notes: address is returned for each mailbox (4) in the array
  141. *
  142. * HIF_DEVICE_GET_PENDING_EVENTS_FUNC
  143. * input : none
  144. * output: HIF_PENDING_EVENTS_FUNC function pointer
  145. * notes: this is optional for the HIF layer, if the request is
  146. * not handled then it indicates that the upper layer can use
  147. * the standard device methods to get pending events (IRQs, mailbox messages etc..)
  148. * otherwise it can call the function pointer to check pending events.
  149. *
  150. * HIF_DEVICE_GET_IRQ_PROC_MODE
  151. * input : none
  152. * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode)
  153. * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF
  154. * layer can report whether IRQ processing is requires synchronous behavior or
  155. * can be processed using asynchronous bus requests (typically faster).
  156. *
  157. * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC
  158. * input :
  159. * output : HIF_MASK_UNMASK_RECV_EVENT function pointer
  160. * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism
  161. * to mask receive message events. The upper layer can call this pointer when it needs
  162. * to mask/unmask receive events (in case it runs out of buffers).
  163. *
  164. * HIF_DEVICE_POWER_STATE_CHANGE
  165. *
  166. * input : HIF_DEVICE_POWER_CHANGE_TYPE
  167. * output : none
  168. * note: this is optional for the HIF layer. The HIF layer can handle power on/off state change
  169. * requests in an interconnect specific way. This is highly OS and bus driver dependent.
  170. * The caller must guarantee that no HIF read/write requests will be made after the device
  171. * is powered down.
  172. *
  173. * HIF_DEVICE_GET_IRQ_YIELD_PARAMS
  174. *
  175. * input : none
  176. * output : HIF_DEVICE_IRQ_YIELD_PARAMS
  177. * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler.
  178. * The DSR callback handler will exit after a fixed number of RX packets or events are processed.
  179. * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY.
  180. * The HIF implementation can ignore this command if it does not desire the DSR callback to yield.
  181. * The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the
  182. * DSR handler callback must yield and return control back to the HIF layer. When a yield limit is
  183. * used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning.
  184. * The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared
  185. * to process interrupts again.
  186. *
  187. * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT
  188. * input : none
  189. * output : HIF_DEVICE_SCATTER_SUPPORT_INFO
  190. * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests
  191. * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for
  192. * multi-message transfers that can better utilize the bus interconnect.
  193. *
  194. *
  195. * HIF_DEVICE_GET_OS_DEVICE
  196. * intput : none
  197. * output : HIF_DEVICE_OS_DEVICE_INFO;
  198. * note: On some operating systems, the HIF layer has a parent device object for the bus. This object
  199. * may be required to register certain types of logical devices.
  200. *
  201. */
  202. typedef struct {
  203. A_UINT32 ExtendedAddress; /* extended address for larger writes */
  204. A_UINT32 ExtendedSize;
  205. } HIF_MBOX_PROPERTIES;
  206. typedef struct {
  207. A_UINT32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in
  208. and ARRAY of 32-bit words */
  209. /* the following describe extended mailbox properties */
  210. HIF_MBOX_PROPERTIES MboxProp[4];
  211. /* if the HIF supports the GMbox extended address region it can report it
  212. * here, some interfaces cannot support the GMBOX address range and not set this */
  213. A_UINT32 GMboxAddress;
  214. A_UINT32 GMboxSize;
  215. } HIF_DEVICE_MBOX_INFO;
  216. typedef enum {
  217. HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all
  218. interrupts before returning */
  219. HIF_DEVICE_IRQ_ASYNC_SYNC, /* for HIF implementations that allow DSR to process interrupts
  220. using ASYNC I/O (that is HIFAckInterrupt can be called at a
  221. later time */
  222. } HIF_DEVICE_IRQ_PROCESSING_MODE;
  223. typedef enum {
  224. HIF_DEVICE_POWER_UP, /* HIF layer should power up interface and/or module */
  225. HIF_DEVICE_POWER_DOWN, /* HIF layer should initiate bus-specific measures to minimize power */
  226. HIF_DEVICE_POWER_CUT /* HIF layer should initiate bus-specific AND/OR platform-specific measures
  227. to completely power-off the module and associated hardware (i.e. cut power supplies)
  228. */
  229. } HIF_DEVICE_POWER_CHANGE_TYPE;
  230. typedef struct {
  231. int RecvPacketYieldCount; /* max number of packets to force DSR to return */
  232. } HIF_DEVICE_IRQ_YIELD_PARAMS;
  233. typedef struct _HIF_SCATTER_ITEM {
  234. A_UINT8 *pBuffer; /* CPU accessible address of buffer */
  235. int Length; /* length of transfer to/from this buffer */
  236. void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */
  237. } HIF_SCATTER_ITEM;
  238. struct _HIF_SCATTER_REQ;
  239. typedef void ( *HIF_SCATTER_COMP_CB)(struct _HIF_SCATTER_REQ *);
  240. typedef enum _HIF_SCATTER_METHOD {
  241. HIF_SCATTER_NONE = 0,
  242. HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */
  243. HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */
  244. } HIF_SCATTER_METHOD;
  245. typedef struct _HIF_SCATTER_REQ {
  246. DL_LIST ListLink; /* link management */
  247. A_UINT32 Address; /* address for the read/write operation */
  248. A_UINT32 Request; /* request flags */
  249. A_UINT32 TotalLength; /* total length of entire transfer */
  250. A_UINT32 CallerFlags; /* caller specific flags can be stored here */
  251. HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */
  252. A_STATUS CompletionStatus; /* status of completion */
  253. void *Context; /* caller context for this request */
  254. int ValidScatterEntries; /* number of valid entries set by caller */
  255. HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */
  256. void *HIFPrivate[4]; /* HIF private area */
  257. A_UINT8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */
  258. HIF_SCATTER_ITEM ScatterList[1]; /* start of scatter list */
  259. } HIF_SCATTER_REQ;
  260. typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device);
  261. typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request);
  262. typedef A_STATUS ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request);
  263. typedef struct _HIF_DEVICE_SCATTER_SUPPORT_INFO {
  264. /* information returned from HIF layer */
  265. HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc;
  266. HIF_FREE_SCATTER_REQUEST pFreeReqFunc;
  267. HIF_READWRITE_SCATTER pReadWriteScatterFunc;
  268. int MaxScatterEntries;
  269. int MaxTransferSizePerScatterReq;
  270. } HIF_DEVICE_SCATTER_SUPPORT_INFO;
  271. typedef struct {
  272. void *pOSDevice;
  273. } HIF_DEVICE_OS_DEVICE_INFO;
  274. #define HIF_MAX_DEVICES 1
  275. struct htc_callbacks {
  276. void *context; /* context to pass to the dsrhandler
  277. note : rwCompletionHandler is provided the context passed to HIFReadWrite */
  278. A_STATUS (* rwCompletionHandler)(void *rwContext, A_STATUS status);
  279. A_STATUS (* dsrHandler)(void *context);
  280. };
  281. typedef struct osdrv_callbacks {
  282. void *context; /* context to pass for all callbacks except deviceRemovedHandler
  283. the deviceRemovedHandler is only called if the device is claimed */
  284. A_STATUS (* deviceInsertedHandler)(void *context, void *hif_handle);
  285. A_STATUS (* deviceRemovedHandler)(void *claimedContext, void *hif_handle);
  286. A_STATUS (* deviceSuspendHandler)(void *context);
  287. A_STATUS (* deviceResumeHandler)(void *context);
  288. A_STATUS (* deviceWakeupHandler)(void *context);
  289. } OSDRV_CALLBACKS;
  290. #define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host
  291. needs to read the register table to figure out what */
  292. #define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */
  293. typedef struct _HIF_PENDING_EVENTS_INFO {
  294. A_UINT32 Events;
  295. A_UINT32 LookAhead;
  296. A_UINT32 AvailableRecvBytes;
  297. } HIF_PENDING_EVENTS_INFO;
  298. /* function to get pending events , some HIF modules use special mechanisms
  299. * to detect packet available and other interrupts */
  300. typedef A_STATUS ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device,
  301. HIF_PENDING_EVENTS_INFO *pEvents,
  302. void *AsyncContext);
  303. #define HIF_MASK_RECV TRUE
  304. #define HIF_UNMASK_RECV FALSE
  305. /* function to mask recv events */
  306. typedef A_STATUS ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device,
  307. A_BOOL Mask,
  308. void *AsyncContext);
  309. /*
  310. * This API is used to perform any global initialization of the HIF layer
  311. * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer
  312. *
  313. */
  314. A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks);
  315. /* This API claims the HIF device and provides a context for handling removal.
  316. * The device removal callback is only called when the OSDRV layer claims
  317. * a device. The claimed context must be non-NULL */
  318. void HIFClaimDevice(HIF_DEVICE *device, void *claimedContext);
  319. /* release the claimed device */
  320. void HIFReleaseDevice(HIF_DEVICE *device);
  321. /* This API allows the HTC layer to attach to the HIF device */
  322. A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks);
  323. /* This API detaches the HTC layer from the HIF device */
  324. void HIFDetachHTC(HIF_DEVICE *device);
  325. /*
  326. * This API is used to provide the read/write interface over the specific bus
  327. * interface.
  328. * address - Starting address in the AR6000's address space. For mailbox
  329. * writes, it refers to the start of the mbox boundary. It should
  330. * be ensured that the last byte falls on the mailbox's EOM. For
  331. * mailbox reads, it refers to the end of the mbox boundary.
  332. * buffer - Pointer to the buffer containg the data to be transmitted or
  333. * received.
  334. * length - Amount of data to be transmitted or received.
  335. * request - Characterizes the attributes of the command.
  336. */
  337. A_STATUS
  338. HIFReadWrite(HIF_DEVICE *device,
  339. A_UINT32 address,
  340. A_UCHAR *buffer,
  341. A_UINT32 length,
  342. A_UINT32 request,
  343. void *context);
  344. /*
  345. * This can be initiated from the unload driver context when the OSDRV layer has no more use for
  346. * the device.
  347. */
  348. void HIFShutDownDevice(HIF_DEVICE *device);
  349. /*
  350. * This should translate to an acknowledgment to the bus driver indicating that
  351. * the previous interrupt request has been serviced and the all the relevant
  352. * sources have been cleared. HTC is ready to process more interrupts.
  353. * This should prevent the bus driver from raising an interrupt unless the
  354. * previous one has been serviced and acknowledged using the previous API.
  355. */
  356. void HIFAckInterrupt(HIF_DEVICE *device);
  357. void HIFMaskInterrupt(HIF_DEVICE *device);
  358. void HIFUnMaskInterrupt(HIF_DEVICE *device);
  359. /*
  360. * This set of functions are to be used by the bus driver to notify
  361. * the HIF module about various events.
  362. * These are not implemented if the bus driver provides an alternative
  363. * way for this notification though callbacks for instance.
  364. */
  365. int HIFInsertEventNotify(void);
  366. int HIFRemoveEventNotify(void);
  367. int HIFIRQEventNotify(void);
  368. int HIFRWCompleteEventNotify(void);
  369. A_STATUS
  370. HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
  371. void *config, A_UINT32 configLen);
  372. #ifdef __cplusplus
  373. }
  374. #endif
  375. #endif /* _HIF_H_ */