1//------------------------------------------------------------------------------ 2// <copyright file="hif.h" company="Atheros"> 3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. 4// 5// 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. 9// 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. 17// 18// 19//------------------------------------------------------------------------------ 20//============================================================================== 21// HIF specific declarations and prototypes 22// 23// Author(s): ="Atheros" 24//============================================================================== 25#ifndef _HIF_H_ 26#define _HIF_H_ 27 28#ifdef __cplusplus 29extern "C" { 30#endif /* __cplusplus */ 31 32/* Header files */ 33#include "a_config.h" 34#include "athdefs.h" 35#include "a_types.h" 36#include "a_osapi.h" 37#include "dl_list.h" 38 39 40typedef struct htc_callbacks HTC_CALLBACKS; 41typedef struct hif_device HIF_DEVICE; 42 43/* 44 * direction - Direction of transfer (HIF_READ/HIF_WRITE). 45 */ 46#define HIF_READ 0x00000001 47#define HIF_WRITE 0x00000002 48#define HIF_DIR_MASK (HIF_READ | HIF_WRITE) 49 50/* 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. 56 */ 57#define HIF_BASIC_IO 0x00000004 58#define HIF_EXTENDED_IO 0x00000008 59#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO) 60 61/* 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. 71 */ 72#define HIF_SYNCHRONOUS 0x00000010 73#define HIF_ASYNCHRONOUS 0x00000020 74#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS) 75 76/* 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. 85 */ 86#define HIF_BYTE_BASIS 0x00000040 87#define HIF_BLOCK_BASIS 0x00000080 88#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS) 89 90/* 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). 94 */ 95#define HIF_FIXED_ADDRESS 0x00000100 96#define HIF_INCREMENTAL_ADDRESS 0x00000200 97#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS) 98 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) 131 132typedef enum { 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; 145 146/* 147 * HIF CONFIGURE definitions: 148 * 149 * HIF_DEVICE_GET_MBOX_BLOCK_SIZE 150 * input : none 151 * output : array of 4 A_UINT32s 152 * notes: block size is returned for each mailbox (4) 153 * 154 * HIF_DEVICE_GET_MBOX_ADDR 155 * input : none 156 * output : HIF_DEVICE_MBOX_INFO 157 * notes: 158 * 159 * HIF_DEVICE_GET_PENDING_EVENTS_FUNC 160 * input : none 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. 166 * 167 * HIF_DEVICE_GET_IRQ_PROC_MODE 168 * input : none 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). 173 * 174 * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC 175 * input : 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). 180 * 181 * HIF_DEVICE_POWER_STATE_CHANGE 182 * 183 * input : HIF_DEVICE_POWER_CHANGE_TYPE 184 * output : none 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 188 * is powered down. 189 * 190 * HIF_DEVICE_GET_IRQ_YIELD_PARAMS 191 * 192 * input : none 193 * output : 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. 203 * 204 * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT 205 * input : none 206 * output : 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. 210 * 211 * 212 * HIF_DEVICE_GET_OS_DEVICE 213 * intput : none 214 * output : 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. 217 * 218 * HIF_DEVICE_DEBUG_BUS_STATE 219 * input : none 220 * output : none 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) 223 * 224 */ 225 226typedef struct { 227 A_UINT32 ExtendedAddress; /* extended address for larger writes */ 228 A_UINT32 ExtendedSize; 229} HIF_MBOX_PROPERTIES; 230 231#define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */ 232 233typedef enum _MBOX_BUF_IF_TYPE { 234 MBOX_BUS_IF_SDIO = 0, 235 MBOX_BUS_IF_SPI = 1, 236} MBOX_BUF_IF_TYPE; 237 238typedef struct { 239 A_UINT32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in 240 and ARRAY of 32-bit words */ 241 242 /* the following describe extended mailbox properties */ 243 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 */ 246 A_UINT32 GMboxAddress; 247 A_UINT32 GMboxSize; 248 A_UINT32 Flags; /* flags to describe mbox behavior or usage */ 249 MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */ 250} HIF_DEVICE_MBOX_INFO; 251 252typedef enum { 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 257 later time */ 258} HIF_DEVICE_IRQ_PROCESSING_MODE; 259 260typedef enum { 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) 265 */ 266} HIF_DEVICE_POWER_CHANGE_TYPE; 267 268typedef struct { 269 int RecvPacketYieldCount; /* max number of packets to force DSR to return */ 270} HIF_DEVICE_IRQ_YIELD_PARAMS; 271 272 273typedef struct _HIF_SCATTER_ITEM { 274 A_UINT8 *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 */ 277} HIF_SCATTER_ITEM; 278 279struct _HIF_SCATTER_REQ; 280 281typedef void ( *HIF_SCATTER_COMP_CB)(struct _HIF_SCATTER_REQ *); 282 283typedef enum _HIF_SCATTER_METHOD { 284 HIF_SCATTER_NONE = 0, 285 HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */ 286 HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */ 287} HIF_SCATTER_METHOD; 288 289typedef struct _HIF_SCATTER_REQ { 290 DL_LIST ListLink; /* link management */ 291 A_UINT32 Address; /* address for the read/write operation */ 292 A_UINT32 Request; /* request flags */ 293 A_UINT32 TotalLength; /* total length of entire transfer */ 294 A_UINT32 CallerFlags; /* caller specific flags can be stored here */ 295 HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */ 296 A_STATUS CompletionStatus; /* status of completion */ 297 void *Context; /* caller context for this request */ 298 int ValidScatterEntries; /* number of valid entries set by caller */ 299 HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */ 300 void *HIFPrivate[4]; /* HIF private area */ 301 A_UINT8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */ 302 HIF_SCATTER_ITEM ScatterList[1]; /* start of scatter list */ 303} HIF_SCATTER_REQ; 304 305typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); 306typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); 307typedef A_STATUS ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); 308 309typedef struct _HIF_DEVICE_SCATTER_SUPPORT_INFO { 310 /* information returned from HIF layer */ 311 HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc; 312 HIF_FREE_SCATTER_REQUEST pFreeReqFunc; 313 HIF_READWRITE_SCATTER pReadWriteScatterFunc; 314 int MaxScatterEntries; 315 int MaxTransferSizePerScatterReq; 316} HIF_DEVICE_SCATTER_SUPPORT_INFO; 317 318typedef struct { 319 void *pOSDevice; 320} HIF_DEVICE_OS_DEVICE_INFO; 321 322#define HIF_MAX_DEVICES 1 323 324struct htc_callbacks { 325 void *context; /* context to pass to the dsrhandler 326 note : rwCompletionHandler is provided the context passed to HIFReadWrite */ 327 A_STATUS (* rwCompletionHandler)(void *rwContext, A_STATUS status); 328 A_STATUS (* dsrHandler)(void *context); 329}; 330 331typedef struct osdrv_callbacks { 332 void *context; /* context to pass for all callbacks except deviceRemovedHandler 333 the deviceRemovedHandler is only called if the device is claimed */ 334 A_STATUS (* deviceInsertedHandler)(void *context, void *hif_handle); 335 A_STATUS (* deviceRemovedHandler)(void *claimedContext, void *hif_handle); 336 A_STATUS (* deviceSuspendHandler)(void *context); 337 A_STATUS (* deviceResumeHandler)(void *context); 338 A_STATUS (* deviceWakeupHandler)(void *context); 339 A_STATUS (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config); 340} OSDRV_CALLBACKS; 341 342#define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host 343 needs to read the register table to figure out what */ 344#define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */ 345 346typedef struct _HIF_PENDING_EVENTS_INFO { 347 A_UINT32 Events; 348 A_UINT32 LookAhead; 349 A_UINT32 AvailableRecvBytes; 350#ifdef THREAD_X 351 A_UINT32 Polling; 352 A_UINT32 INT_CAUSE_REG; 353#endif 354} HIF_PENDING_EVENTS_INFO; 355 356 /* function to get pending events , some HIF modules use special mechanisms 357 * to detect packet available and other interrupts */ 358typedef A_STATUS ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, 359 HIF_PENDING_EVENTS_INFO *pEvents, 360 void *AsyncContext); 361 362#define HIF_MASK_RECV TRUE 363#define HIF_UNMASK_RECV FALSE 364 /* function to mask recv events */ 365typedef A_STATUS ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, 366 A_BOOL Mask, 367 void *AsyncContext); 368 369 370/* 371 * This API is used to perform any global initialization of the HIF layer 372 * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer 373 * 374 */ 375A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks); 376 377/* This API claims the HIF device and provides a context for handling removal. 378 * The device removal callback is only called when the OSDRV layer claims 379 * a device. The claimed context must be non-NULL */ 380void HIFClaimDevice(HIF_DEVICE *device, void *claimedContext); 381/* release the claimed device */ 382void HIFReleaseDevice(HIF_DEVICE *device); 383 384/* This API allows the HTC layer to attach to the HIF device */ 385A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks); 386/* This API detaches the HTC layer from the HIF device */ 387void HIFDetachHTC(HIF_DEVICE *device); 388 389/* 390 * This API is used to provide the read/write interface over the specific bus 391 * interface. 392 * address - Starting address in the AR6000's address space. For mailbox 393 * writes, it refers to the start of the mbox boundary. It should 394 * be ensured that the last byte falls on the mailbox's EOM. For 395 * mailbox reads, it refers to the end of the mbox boundary. 396 * buffer - Pointer to the buffer containg the data to be transmitted or 397 * received. 398 * length - Amount of data to be transmitted or received. 399 * request - Characterizes the attributes of the command. 400 */ 401A_STATUS 402HIFReadWrite(HIF_DEVICE *device, 403 A_UINT32 address, 404 A_UCHAR *buffer, 405 A_UINT32 length, 406 A_UINT32 request, 407 void *context); 408 409/* 410 * This can be initiated from the unload driver context when the OSDRV layer has no more use for 411 * the device. 412 */ 413void HIFShutDownDevice(HIF_DEVICE *device); 414 415/* 416 * This should translate to an acknowledgment to the bus driver indicating that 417 * the previous interrupt request has been serviced and the all the relevant 418 * sources have been cleared. HTC is ready to process more interrupts. 419 * This should prevent the bus driver from raising an interrupt unless the 420 * previous one has been serviced and acknowledged using the previous API. 421 */ 422void HIFAckInterrupt(HIF_DEVICE *device); 423 424void HIFMaskInterrupt(HIF_DEVICE *device); 425 426void HIFUnMaskInterrupt(HIF_DEVICE *device); 427 428#ifdef THREAD_X 429/* 430 * This set of functions are to be used by the bus driver to notify 431 * the HIF module about various events. 432 * These are not implemented if the bus driver provides an alternative 433 * way for this notification though callbacks for instance. 434 */ 435int HIFInsertEventNotify(void); 436 437int HIFRemoveEventNotify(void); 438 439int HIFIRQEventNotify(void); 440 441int HIFRWCompleteEventNotify(void); 442#endif 443 444A_STATUS 445HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, 446 void *config, A_UINT32 configLen); 447 448/* 449 * This API wait for the remaining MBOX messages to be drained 450 * This should be moved to HTC AR6K layer 451 */ 452A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device); 453 454#ifdef __cplusplus 455} 456#endif 457 458#endif /* _HIF_H_ */ 459