1 //------------------------------------------------------------------------------
2 // <copyright file="hif.h" company="Atheros">
3 // Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
6 // Permission to use, copy, modify, and/or distribute this software for any
7 // purpose with or without fee is hereby granted, provided that the above
8 // copyright notice and this permission notice appear in all copies.
10 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 //------------------------------------------------------------------------------
20 //==============================================================================
21 // HIF specific declarations and prototypes
23 // Author(s): ="Atheros"
24 //==============================================================================
30 #endif /* __cplusplus */
40 typedef struct htc_callbacks HTC_CALLBACKS
;
44 * direction - Direction of transfer (HIF_READ/HIF_WRITE).
46 #define HIF_READ 0x00000001
47 #define HIF_WRITE 0x00000002
48 #define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
51 * type - An interface may support different kind of read/write commands.
52 * For example: SDIO supports CMD52/CMD53s. In case of MSIO it
53 * translates to using different kinds of TPCs. The command type
54 * is thus divided into a basic and an extended command and can
55 * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
57 #define HIF_BASIC_IO 0x00000004
58 #define HIF_EXTENDED_IO 0x00000008
59 #define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO)
62 * emode - This indicates the whether the command is to be executed in a
63 * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
64 * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
65 * implemented using the asynchronous mode allowing the the bus
66 * driver to indicate the completion of operation through the
67 * registered callback routine. The requirement primarily comes
68 * from the contexts these operations get called from (a driver's
69 * transmit context or the ISR context in case of receive).
70 * Support for both of these modes is essential.
72 #define HIF_SYNCHRONOUS 0x00000010
73 #define HIF_ASYNCHRONOUS 0x00000020
74 #define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
77 * dmode - An interface may support different kinds of commands based on
78 * the tradeoff between the amount of data it can carry and the
79 * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
80 * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
81 * to the nearest block size by padding. The size of the block is
82 * configurable at compile time using the HIF_BLOCK_SIZE and is
83 * negotiated with the target during initialization after the
84 * AR6000 interrupts are enabled.
86 #define HIF_BYTE_BASIS 0x00000040
87 #define HIF_BLOCK_BASIS 0x00000080
88 #define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
91 * amode - This indicates if the address has to be incremented on AR6000
92 * after every read/write operation (HIF?FIXED_ADDRESS/
93 * HIF_INCREMENTAL_ADDRESS).
95 #define HIF_FIXED_ADDRESS 0x00000100
96 #define HIF_INCREMENTAL_ADDRESS 0x00000200
97 #define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
99 #define HIF_WR_ASYNC_BYTE_FIX \
100 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
101 #define HIF_WR_ASYNC_BYTE_INC \
102 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
103 #define HIF_WR_ASYNC_BLOCK_INC \
104 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
105 #define HIF_WR_SYNC_BYTE_FIX \
106 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
107 #define HIF_WR_SYNC_BYTE_INC \
108 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
109 #define HIF_WR_SYNC_BLOCK_INC \
110 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
111 #define HIF_WR_ASYNC_BLOCK_FIX \
112 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
113 #define HIF_WR_SYNC_BLOCK_FIX \
114 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
115 #define HIF_RD_SYNC_BYTE_INC \
116 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
117 #define HIF_RD_SYNC_BYTE_FIX \
118 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
119 #define HIF_RD_ASYNC_BYTE_FIX \
120 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
121 #define HIF_RD_ASYNC_BLOCK_FIX \
122 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
123 #define HIF_RD_ASYNC_BYTE_INC \
124 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
125 #define HIF_RD_ASYNC_BLOCK_INC \
126 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
127 #define HIF_RD_SYNC_BLOCK_INC \
128 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
129 #define HIF_RD_SYNC_BLOCK_FIX \
130 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
133 HIF_DEVICE_POWER_STATE
= 0,
134 HIF_DEVICE_GET_MBOX_BLOCK_SIZE
,
135 HIF_DEVICE_GET_MBOX_ADDR
,
136 HIF_DEVICE_GET_PENDING_EVENTS_FUNC
,
137 HIF_DEVICE_GET_IRQ_PROC_MODE
,
138 HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC
,
139 HIF_DEVICE_POWER_STATE_CHANGE
,
140 HIF_DEVICE_GET_IRQ_YIELD_PARAMS
,
141 HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT
,
142 HIF_DEVICE_GET_OS_DEVICE
,
143 HIF_DEVICE_DEBUG_BUS_STATE
,
144 } HIF_DEVICE_CONFIG_OPCODE
;
147 * HIF CONFIGURE definitions:
149 * HIF_DEVICE_GET_MBOX_BLOCK_SIZE
151 * output : array of 4 A_UINT32s
152 * notes: block size is returned for each mailbox (4)
154 * HIF_DEVICE_GET_MBOX_ADDR
156 * output : struct hif_device_mbox_info
159 * HIF_DEVICE_GET_PENDING_EVENTS_FUNC
161 * output: HIF_PENDING_EVENTS_FUNC function pointer
162 * notes: this is optional for the HIF layer, if the request is
163 * not handled then it indicates that the upper layer can use
164 * the standard device methods to get pending events (IRQs, mailbox messages etc..)
165 * otherwise it can call the function pointer to check pending events.
167 * HIF_DEVICE_GET_IRQ_PROC_MODE
169 * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode)
170 * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF
171 * layer can report whether IRQ processing is requires synchronous behavior or
172 * can be processed using asynchronous bus requests (typically faster).
174 * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC
176 * output : HIF_MASK_UNMASK_RECV_EVENT function pointer
177 * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism
178 * to mask receive message events. The upper layer can call this pointer when it needs
179 * to mask/unmask receive events (in case it runs out of buffers).
181 * HIF_DEVICE_POWER_STATE_CHANGE
183 * input : HIF_DEVICE_POWER_CHANGE_TYPE
185 * note: this is optional for the HIF layer. The HIF layer can handle power on/off state change
186 * requests in an interconnect specific way. This is highly OS and bus driver dependent.
187 * The caller must guarantee that no HIF read/write requests will be made after the device
190 * HIF_DEVICE_GET_IRQ_YIELD_PARAMS
193 * output : struct hif_device_irq_yield_params
194 * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler.
195 * The DSR callback handler will exit after a fixed number of RX packets or events are processed.
196 * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY.
197 * The HIF implementation can ignore this command if it does not desire the DSR callback to yield.
198 * The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the
199 * DSR handler callback must yield and return control back to the HIF layer. When a yield limit is
200 * used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning.
201 * The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared
202 * to process interrupts again.
204 * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT
206 * output : struct hif_device_scatter_support_info
207 * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests
208 * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for
209 * multi-message transfers that can better utilize the bus interconnect.
212 * HIF_DEVICE_GET_OS_DEVICE
214 * output : struct hif_device_os_device_info;
215 * note: On some operating systems, the HIF layer has a parent device object for the bus. This object
216 * may be required to register certain types of logical devices.
218 * HIF_DEVICE_DEBUG_BUS_STATE
221 * note: This configure option triggers the HIF interface to dump as much bus interface state. This
222 * configuration request is optional (No-OP on some HIF implementations)
226 struct hif_mbox_properties
{
227 u32 ExtendedAddress
; /* extended address for larger writes */
231 #define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */
233 typedef enum _MBOX_BUF_IF_TYPE
{
234 MBOX_BUS_IF_SDIO
= 0,
238 struct hif_device_mbox_info
{
239 u32 MboxAddresses
[4]; /* must be first element for legacy HIFs that return the address in
240 and ARRAY of 32-bit words */
242 /* the following describe extended mailbox properties */
243 struct hif_mbox_properties MboxProp
[4];
244 /* if the HIF supports the GMbox extended address region it can report it
245 * here, some interfaces cannot support the GMBOX address range and not set this */
248 u32 Flags
; /* flags to describe mbox behavior or usage */
249 MBOX_BUF_IF_TYPE MboxBusIFType
; /* mailbox bus interface type */
253 HIF_DEVICE_IRQ_SYNC_ONLY
, /* for HIF implementations that require the DSR to process all
254 interrupts before returning */
255 HIF_DEVICE_IRQ_ASYNC_SYNC
, /* for HIF implementations that allow DSR to process interrupts
256 using ASYNC I/O (that is HIFAckInterrupt can be called at a
258 } HIF_DEVICE_IRQ_PROCESSING_MODE
;
261 HIF_DEVICE_POWER_UP
, /* HIF layer should power up interface and/or module */
262 HIF_DEVICE_POWER_DOWN
, /* HIF layer should initiate bus-specific measures to minimize power */
263 HIF_DEVICE_POWER_CUT
/* HIF layer should initiate bus-specific AND/OR platform-specific measures
264 to completely power-off the module and associated hardware (i.e. cut power supplies)
266 } HIF_DEVICE_POWER_CHANGE_TYPE
;
268 struct hif_device_irq_yield_params
{
269 int RecvPacketYieldCount
; /* max number of packets to force DSR to return */
273 struct hif_scatter_item
{
274 u8
*pBuffer
; /* CPU accessible address of buffer */
275 int Length
; /* length of transfer to/from this buffer */
276 void *pCallerContexts
[2]; /* space for caller to insert a context associated with this item */
279 struct hif_scatter_req
;
280 typedef void ( *HIF_SCATTER_COMP_CB
)(struct hif_scatter_req
*);
282 typedef enum _HIF_SCATTER_METHOD
{
283 HIF_SCATTER_NONE
= 0,
284 HIF_SCATTER_DMA_REAL
, /* Real SG support no restrictions */
285 HIF_SCATTER_DMA_BOUNCE
, /* Uses SG DMA but HIF layer uses an internal bounce buffer */
286 } HIF_SCATTER_METHOD
;
288 struct hif_scatter_req
{
289 struct dl_list ListLink
; /* link management */
290 u32 Address
; /* address for the read/write operation */
291 u32 Request
; /* request flags */
292 u32 TotalLength
; /* total length of entire transfer */
293 u32 CallerFlags
; /* caller specific flags can be stored here */
294 HIF_SCATTER_COMP_CB CompletionRoutine
; /* completion routine set by caller */
295 int CompletionStatus
; /* status of completion */
296 void *Context
; /* caller context for this request */
297 int ValidScatterEntries
; /* number of valid entries set by caller */
298 HIF_SCATTER_METHOD ScatterMethod
; /* scatter method handled by HIF */
299 void *HIFPrivate
[4]; /* HIF private area */
300 u8
*pScatterBounceBuffer
; /* bounce buffer for upper layers to copy to/from */
301 struct hif_scatter_item ScatterList
[1]; /* start of scatter list */
304 typedef struct hif_scatter_req
* ( *HIF_ALLOCATE_SCATTER_REQUEST
)(struct hif_device
*device
);
305 typedef void ( *HIF_FREE_SCATTER_REQUEST
)(struct hif_device
*device
, struct hif_scatter_req
*request
);
306 typedef int ( *HIF_READWRITE_SCATTER
)(struct hif_device
*device
, struct hif_scatter_req
*request
);
308 struct hif_device_scatter_support_info
{
309 /* information returned from HIF layer */
310 HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc
;
311 HIF_FREE_SCATTER_REQUEST pFreeReqFunc
;
312 HIF_READWRITE_SCATTER pReadWriteScatterFunc
;
313 int MaxScatterEntries
;
314 int MaxTransferSizePerScatterReq
;
317 struct hif_device_os_device_info
{
321 #define HIF_MAX_DEVICES 1
323 struct htc_callbacks
{
324 void *context
; /* context to pass to the dsrhandler
325 note : rwCompletionHandler is provided the context passed to HIFReadWrite */
326 int (* rwCompletionHandler
)(void *rwContext
, int status
);
327 int (* dsrHandler
)(void *context
);
330 typedef struct osdrv_callbacks
{
331 void *context
; /* context to pass for all callbacks except deviceRemovedHandler
332 the deviceRemovedHandler is only called if the device is claimed */
333 int (* deviceInsertedHandler
)(void *context
, void *hif_handle
);
334 int (* deviceRemovedHandler
)(void *claimedContext
, void *hif_handle
);
335 int (* deviceSuspendHandler
)(void *context
);
336 int (* deviceResumeHandler
)(void *context
);
337 int (* deviceWakeupHandler
)(void *context
);
338 int (* devicePowerChangeHandler
)(void *context
, HIF_DEVICE_POWER_CHANGE_TYPE config
);
341 #define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host
342 needs to read the register table to figure out what */
343 #define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */
345 struct hif_pending_events_info
{
348 u32 AvailableRecvBytes
;
355 /* function to get pending events , some HIF modules use special mechanisms
356 * to detect packet available and other interrupts */
357 typedef int ( *HIF_PENDING_EVENTS_FUNC
)(struct hif_device
*device
,
358 struct hif_pending_events_info
*pEvents
,
361 #define HIF_MASK_RECV true
362 #define HIF_UNMASK_RECV false
363 /* function to mask recv events */
364 typedef int ( *HIF_MASK_UNMASK_RECV_EVENT
)(struct hif_device
*device
,
370 * This API is used to perform any global initialization of the HIF layer
371 * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer
374 int HIFInit(OSDRV_CALLBACKS
*callbacks
);
376 /* This API claims the HIF device and provides a context for handling removal.
377 * The device removal callback is only called when the OSDRV layer claims
378 * a device. The claimed context must be non-NULL */
379 void HIFClaimDevice(struct hif_device
*device
, void *claimedContext
);
380 /* release the claimed device */
381 void HIFReleaseDevice(struct hif_device
*device
);
383 /* This API allows the HTC layer to attach to the HIF device */
384 int HIFAttachHTC(struct hif_device
*device
, HTC_CALLBACKS
*callbacks
);
385 /* This API detaches the HTC layer from the HIF device */
386 void HIFDetachHTC(struct hif_device
*device
);
389 * This API is used to provide the read/write interface over the specific bus
391 * address - Starting address in the AR6000's address space. For mailbox
392 * writes, it refers to the start of the mbox boundary. It should
393 * be ensured that the last byte falls on the mailbox's EOM. For
394 * mailbox reads, it refers to the end of the mbox boundary.
395 * buffer - Pointer to the buffer containg the data to be transmitted or
397 * length - Amount of data to be transmitted or received.
398 * request - Characterizes the attributes of the command.
401 HIFReadWrite(struct hif_device
*device
,
409 * This can be initiated from the unload driver context when the OSDRV layer has no more use for
412 void HIFShutDownDevice(struct hif_device
*device
);
415 * This should translate to an acknowledgment to the bus driver indicating that
416 * the previous interrupt request has been serviced and the all the relevant
417 * sources have been cleared. HTC is ready to process more interrupts.
418 * This should prevent the bus driver from raising an interrupt unless the
419 * previous one has been serviced and acknowledged using the previous API.
421 void HIFAckInterrupt(struct hif_device
*device
);
423 void HIFMaskInterrupt(struct hif_device
*device
);
425 void HIFUnMaskInterrupt(struct hif_device
*device
);
429 * This set of functions are to be used by the bus driver to notify
430 * the HIF module about various events.
431 * These are not implemented if the bus driver provides an alternative
432 * way for this notification though callbacks for instance.
434 int HIFInsertEventNotify(void);
436 int HIFRemoveEventNotify(void);
438 int HIFIRQEventNotify(void);
440 int HIFRWCompleteEventNotify(void);
444 HIFConfigureDevice(struct hif_device
*device
, HIF_DEVICE_CONFIG_OPCODE opcode
,
445 void *config
, u32 configLen
);
448 * This API wait for the remaining MBOX messages to be drained
449 * This should be moved to HTC AR6K layer
451 int hifWaitForPendingRecv(struct hif_device
*device
);