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 29 extern "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 40 typedef struct htc_callbacks HTC_CALLBACKS; 41 struct 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 132 typedef 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 : struct 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 : 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. 203 * 204 * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT 205 * input : none 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. 210 * 211 * 212 * HIF_DEVICE_GET_OS_DEVICE 213 * intput : none 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. 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 226 struct hif_mbox_properties { 227 u32 ExtendedAddress; /* extended address for larger writes */ 228 u32 ExtendedSize; 229 }; 230 231 #define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */ 232 233 typedef enum _MBOX_BUF_IF_TYPE { 234 MBOX_BUS_IF_SDIO = 0, 235 MBOX_BUS_IF_SPI = 1, 236 } MBOX_BUF_IF_TYPE; 237 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 */ 241 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 */ 246 u32 GMboxAddress; 247 u32 GMboxSize; 248 u32 Flags; /* flags to describe mbox behavior or usage */ 249 MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */ 250 }; 251 252 typedef 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 260 typedef 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 268 struct hif_device_irq_yield_params { 269 int RecvPacketYieldCount; /* max number of packets to force DSR to return */ 270 }; 271 272 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 */ 277 }; 278 279 struct hif_scatter_req; 280 typedef void ( *HIF_SCATTER_COMP_CB)(struct hif_scatter_req *); 281 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; 287 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 */ 302 }; 303 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); 307 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; 315 }; 316 317 struct hif_device_os_device_info { 318 void *pOSDevice; 319 }; 320 321 #define HIF_MAX_DEVICES 1 322 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); 328 }; 329 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); 339 } OSDRV_CALLBACKS; 340 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 */ 344 345 struct hif_pending_events_info { 346 u32 Events; 347 u32 LookAhead; 348 u32 AvailableRecvBytes; 349 #ifdef THREAD_X 350 u32 Polling; 351 u32 INT_CAUSE_REG; 352 #endif 353 }; 354 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, 359 void *AsyncContext); 360 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, 365 bool Mask, 366 void *AsyncContext); 367 368 369 /* 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 372 * 373 */ 374 int HIFInit(OSDRV_CALLBACKS *callbacks); 375 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); 382 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); 387 388 /* 389 * This API is used to provide the read/write interface over the specific bus 390 * interface. 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 396 * received. 397 * length - Amount of data to be transmitted or received. 398 * request - Characterizes the attributes of the command. 399 */ 400 int 401 HIFReadWrite(struct hif_device *device, 402 u32 address, 403 u8 *buffer, 404 u32 length, 405 u32 request, 406 void *context); 407 408 /* 409 * This can be initiated from the unload driver context when the OSDRV layer has no more use for 410 * the device. 411 */ 412 void HIFShutDownDevice(struct hif_device *device); 413 414 /* 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. 420 */ 421 void HIFAckInterrupt(struct hif_device *device); 422 423 void HIFMaskInterrupt(struct hif_device *device); 424 425 void HIFUnMaskInterrupt(struct hif_device *device); 426 427 #ifdef THREAD_X 428 /* 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. 433 */ 434 int HIFInsertEventNotify(void); 435 436 int HIFRemoveEventNotify(void); 437 438 int HIFIRQEventNotify(void); 439 440 int HIFRWCompleteEventNotify(void); 441 #endif 442 443 int 444 HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode, 445 void *config, u32 configLen); 446 447 /* 448 * This API wait for the remaining MBOX messages to be drained 449 * This should be moved to HTC AR6K layer 450 */ 451 int hifWaitForPendingRecv(struct hif_device *device); 452 453 #ifdef __cplusplus 454 } 455 #endif 456 457 #endif /* _HIF_H_ */ 458