1 /* 2 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #ifndef _HIF_INTERNAL_H_ 21 #define _HIF_INTERNAL_H_ 22 23 #include <linux/mmc/card.h> 24 #include <linux/mmc/mmc.h> 25 #include <linux/mmc/host.h> 26 #include <linux/mmc/sdio_func.h> 27 #include <linux/mmc/sdio_ids.h> 28 #include <linux/mmc/sdio.h> 29 #include <linux/mmc/sd.h> 30 31 #include "athdefs.h" 32 #include "a_types.h" 33 #include "a_osapi.h" 34 #include <qdf_types.h> /* qdf_device_t, qdf_print */ 35 #include <qdf_time.h> /* qdf_system_ticks, etc. */ 36 #include <qdf_status.h> 37 #include <qdf_timer.h> 38 #include <qdf_atomic.h> 39 #include <qdf_list.h> 40 #include "hif.h" 41 #include "hif_debug.h" 42 #include "hif_sdio_common.h" 43 #include <linux/scatterlist.h> 44 #include "hif_main.h" 45 46 #define HIF_LINUX_MMC_SCATTER_SUPPORT 47 48 #define BUS_REQUEST_MAX_NUM 105 49 50 #define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000 51 #define SDWLAN_ENABLE_DISABLE_TIMEOUT 20 52 #define FLAGS_CARD_ENAB 0x02 53 #define FLAGS_CARD_IRQ_UNMSK 0x04 54 55 /* 56 * direction - Direction of transfer (HIF_SDIO_READ/HIF_SDIO_WRITE). 57 */ 58 #define HIF_SDIO_READ 0x00000001 59 #define HIF_SDIO_WRITE 0x00000002 60 #define HIF_SDIO_DIR_MASK (HIF_SDIO_READ | HIF_SDIO_WRITE) 61 62 /* 63 * type - An interface may support different kind of rd/wr commands. 64 * For example: SDIO supports CMD52/CMD53s. In case of MSIO it 65 * translates to using different kinds of TPCs. The command type 66 * is thus divided into a basic and an extended command and can 67 * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO. 68 */ 69 #define HIF_BASIC_IO 0x00000004 70 #define HIF_EXTENDED_IO 0x00000008 71 #define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO) 72 73 /* 74 * This indicates the whether the command is to be executed in a 75 * blocking or non-blocking fashion (HIF_SYNCHRONOUS/ 76 * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been 77 * implemented using the asynchronous mode allowing the the bus 78 * driver to indicate the completion of operation through the 79 * registered callback routine. The requirement primarily comes 80 * from the contexts these operations get called from (a driver's 81 * transmit context or the ISR context in case of receive). 82 * Support for both of these modes is essential. 83 */ 84 #define HIF_SYNCHRONOUS 0x00000010 85 #define HIF_ASYNCHRONOUS 0x00000020 86 #define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS) 87 88 /* 89 * An interface may support different kinds of commands based on 90 * the tradeoff between the amount of data it can carry and the 91 * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/ 92 * HIF_BLOCK_BASIS). In case of latter, the data is rounded off 93 * to the nearest block size by padding. The size of the block is 94 * configurable at compile time using the HIF_BLOCK_SIZE and is 95 * negotiated with the target during initialization after the 96 * AR6000 interrupts are enabled. 97 */ 98 #define HIF_BYTE_BASIS 0x00000040 99 #define HIF_BLOCK_BASIS 0x00000080 100 #define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS) 101 102 /* 103 * This indicates if the address has to be incremented on AR6000 104 * after every read/write operation (HIF?FIXED_ADDRESS/ 105 * HIF_INCREMENTAL_ADDRESS). 106 */ 107 #define HIF_FIXED_ADDRESS 0x00000100 108 #define HIF_INCREMENTAL_ADDRESS 0x00000200 109 #define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | \ 110 HIF_INCREMENTAL_ADDRESS) 111 112 #define HIF_WR_ASYNC_BYTE_FIX \ 113 (HIF_SDIO_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 114 HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) 115 #define HIF_WR_ASYNC_BYTE_INC \ 116 (HIF_SDIO_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 117 HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) 118 #define HIF_WR_ASYNC_BLOCK_INC \ 119 (HIF_SDIO_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 120 HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) 121 #define HIF_WR_SYNC_BYTE_FIX \ 122 (HIF_SDIO_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 123 HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) 124 #define HIF_WR_SYNC_BYTE_INC \ 125 (HIF_SDIO_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 126 HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) 127 #define HIF_WR_SYNC_BLOCK_INC \ 128 (HIF_SDIO_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 129 HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) 130 #define HIF_WR_ASYNC_BLOCK_FIX \ 131 (HIF_SDIO_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 132 HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) 133 #define HIF_WR_SYNC_BLOCK_FIX \ 134 (HIF_SDIO_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 135 HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) 136 #define HIF_RD_SYNC_BYTE_INC \ 137 (HIF_SDIO_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 138 HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) 139 #define HIF_RD_SYNC_BYTE_FIX \ 140 (HIF_SDIO_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 141 HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) 142 #define HIF_RD_ASYNC_BYTE_FIX \ 143 (HIF_SDIO_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 144 HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) 145 #define HIF_RD_ASYNC_BLOCK_FIX \ 146 (HIF_SDIO_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 147 HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) 148 #define HIF_RD_ASYNC_BYTE_INC \ 149 (HIF_SDIO_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 150 HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) 151 #define HIF_RD_ASYNC_BLOCK_INC \ 152 (HIF_SDIO_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ 153 HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) 154 #define HIF_RD_SYNC_BLOCK_INC \ 155 (HIF_SDIO_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 156 HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) 157 #define HIF_RD_SYNC_BLOCK_FIX \ 158 (HIF_SDIO_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | \ 159 HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) 160 161 enum hif_sdio_device_state { 162 HIF_DEVICE_STATE_ON, 163 HIF_DEVICE_STATE_DEEPSLEEP, 164 HIF_DEVICE_STATE_CUTPOWER, 165 HIF_DEVICE_STATE_WOW 166 }; 167 168 struct bus_request { 169 struct bus_request *next; /* link list of available requests */ 170 struct bus_request *inusenext; /* link list of in use requests */ 171 struct semaphore sem_req; 172 unsigned long address; /* request data */ 173 char *buffer; 174 uint32_t length; 175 uint32_t request; 176 void *context; 177 QDF_STATUS status; 178 struct HIF_SCATTER_REQ_PRIV *scatter_req; 179 }; 180 181 #define HIF_ADMA_MAX_CHANS 2 182 #ifdef CONFIG_SDIO_TRANSFER_ADMA 183 struct rx_q_entry { 184 qdf_list_node_t entry; 185 qdf_nbuf_t nbuf; 186 }; 187 #endif 188 189 struct hif_sdio_dev { 190 struct sdio_func *func; 191 qdf_spinlock_t asynclock; 192 struct task_struct *async_task; /* task to handle async commands */ 193 struct semaphore sem_async; /* wake up for async task */ 194 int async_shutdown; /* stop the async task */ 195 struct completion async_completion; /* thread completion */ 196 struct bus_request *asyncreq; /* request for async tasklet */ 197 struct bus_request *taskreq; /* async tasklet data */ 198 qdf_spinlock_t lock; 199 struct bus_request *bus_request_free_queue; /* free list */ 200 struct bus_request bus_request[BUS_REQUEST_MAX_NUM]; /* bus requests */ 201 void *claimed_ctx; 202 struct htc_callbacks htc_callbacks; 203 uint8_t *dma_buffer; 204 DL_LIST scatter_req_head; /* scatter request list head */ 205 bool scatter_enabled; /* scatter enabled flag */ 206 bool is_suspend; 207 bool is_disabled; 208 atomic_t irq_handling; 209 enum HIF_DEVICE_POWER_CHANGE_TYPE power_config; 210 enum hif_sdio_device_state device_state; 211 const struct sdio_device_id *id; 212 struct mmc_host *host; 213 void *htc_context; 214 #ifdef CONFIG_SDIO_TRANSFER_ADMA 215 struct sdio_al_client_handle *al_client; 216 struct sdio_al_channel_handle *al_chan[HIF_ADMA_MAX_CHANS]; 217 uint8_t adma_chans_used; 218 qdf_list_t rx_q; 219 qdf_spinlock_t rx_q_lock; 220 qdf_work_t rx_q_alloc_work; 221 bool rx_q_alloc_work_scheduled; 222 #endif 223 }; 224 225 struct HIF_DEVICE_OS_DEVICE_INFO { 226 void *os_dev; 227 }; 228 229 struct hif_mailbox_properties { 230 u_int32_t extended_address; /* extended address for larger writes */ 231 u_int32_t extended_size; 232 }; 233 234 struct hif_device_irq_yield_params { 235 int recv_packet_yield_count; 236 /* max number of packets to force DSR to return */ 237 }; 238 239 struct hif_device_mbox_info { 240 u_int32_t mbox_addresses[4]; 241 /* first element for legacy HIFs and return the address and ARRAY of 242 * 32bit words 243 */ 244 struct hif_mailbox_properties mbox_prop[4]; 245 u_int32_t gmbox_address; 246 u_int32_t gmbox_size; 247 u_int32_t flags; 248 /* flags to describe mbox behavior or usage */ 249 }; 250 251 enum hif_device_irq_mode { 252 HIF_DEVICE_IRQ_SYNC_ONLY, 253 /* DSR to process all interrupts before returning */ 254 HIF_DEVICE_IRQ_ASYNC_SYNC, /* DSR to process interrupts */ 255 }; 256 257 /* other interrupts are pending, host 258 * needs to read the to monitor 259 */ 260 #define HIF_OTHER_EVENTS (1 << 0) 261 /* pending recv packet */ 262 #define HIF_RECV_MSG_AVAIL (1 << 1) 263 264 struct _HIF_PENDING_EVENTS_INFO { 265 uint32_t events; 266 uint32_t look_ahead; 267 uint32_t available_recv_bytes; 268 }; 269 270 /* hif-sdio pending events handler type, some HIF modules 271 * use special mechanisms to detect packet available and other interrupts 272 */ 273 typedef int (*HIF_PENDING_EVENTS_FUNC)(struct hif_sdio_dev *device, 274 struct _HIF_PENDING_EVENTS_INFO * 275 events, void *async_context); 276 277 #define HIF_MASK_RECV true 278 #define HIF_UNMASK_RECV false 279 /* hif-sdio Handler type to mask receive events */ 280 typedef int (*HIF_MASK_UNMASK_RECV_EVENT)(struct hif_sdio_dev *device, 281 bool mask, 282 void *async_context); 283 284 QDF_STATUS hif_configure_device(struct hif_softc *ol_sc, 285 struct hif_sdio_dev *device, 286 enum hif_device_config_opcode opcode, 287 void *config, uint32_t config_len); 288 289 QDF_STATUS hif_attach_htc(struct hif_sdio_dev *device, 290 struct htc_callbacks *callbacks); 291 292 void hif_ack_interrupt(struct hif_sdio_dev *device); 293 294 void hif_mask_interrupt(struct hif_sdio_dev *device); 295 296 void hif_un_mask_interrupt(struct hif_sdio_dev *device); 297 298 int hif_sdio_configure_pipes(struct hif_sdio_dev *dev, struct sdio_func *func); 299 300 struct _HIF_SCATTER_ITEM { 301 u_int8_t *buffer; /* CPU accessible address of buffer */ 302 int length; /* length of transfer to/from this buffer */ 303 void *caller_contexts[2]; /* caller context */ 304 }; 305 306 struct _HIF_SCATTER_REQ; 307 308 typedef void (*HIF_SCATTER_COMP_CB)(struct _HIF_SCATTER_REQ *); 309 310 enum HIF_SCATTER_METHOD { 311 HIF_SCATTER_NONE = 0, 312 HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */ 313 HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA */ 314 }; 315 316 struct _HIF_SCATTER_REQ { 317 DL_LIST list_link; /* link management */ 318 u_int32_t address; /* address for the read/write operation */ 319 u_int32_t request; /* request flags */ 320 u_int32_t total_length; /* total length of entire transfer */ 321 u_int32_t caller_flags; /* caller specific flags */ 322 HIF_SCATTER_COMP_CB completion_routine; /* completion callback */ 323 int completion_status; /* status of completion */ 324 void *context; /* caller context for this request */ 325 int valid_scatter_entries; /* no of valid entries */ 326 /* scatter method handled by HIF */ 327 enum HIF_SCATTER_METHOD scatter_method; 328 void *hif_private[4]; /* HIF private area */ 329 u_int8_t *scatter_bounce_buffer; /* bounce buffers */ 330 QDF_FLEX_ARRAY(struct _HIF_SCATTER_ITEM, scatter_list); /* start of scatter list */ 331 }; 332 333 typedef struct _HIF_SCATTER_REQ * (*HIF_ALLOCATE_SCATTER_REQUEST)( 334 struct hif_sdio_dev *device); 335 typedef void (*HIF_FREE_SCATTER_REQUEST)(struct hif_sdio_dev *device, 336 struct _HIF_SCATTER_REQ *request); 337 typedef QDF_STATUS (*HIF_READWRITE_SCATTER)(struct hif_sdio_dev *device, 338 struct _HIF_SCATTER_REQ *request); 339 340 struct HIF_DEVICE_SCATTER_SUPPORT_INFO { 341 /* information returned from HIF layer */ 342 HIF_ALLOCATE_SCATTER_REQUEST allocate_req_func; 343 HIF_FREE_SCATTER_REQUEST free_req_func; 344 HIF_READWRITE_SCATTER read_write_scatter_func; 345 int max_scatter_entries; 346 int max_tx_size_per_scatter_req; 347 }; 348 349 void hif_get_target_revision(struct hif_softc *ol_sc); 350 struct HIF_SCATTER_REQ_PRIV; 351 352 #define HIF_DMA_BUFFER_SIZE (4 * 1024) 353 #define CMD53_FIXED_ADDRESS 1 354 #define CMD53_INCR_ADDRESS 2 355 356 struct bus_request *hif_allocate_bus_request(struct hif_sdio_dev *device); 357 void hif_free_bus_request(struct hif_sdio_dev *device, 358 struct bus_request *busrequest); 359 void add_to_async_list(struct hif_sdio_dev *device, 360 struct bus_request *busrequest); 361 void hif_dump_cccr(struct hif_sdio_dev *hif_device); 362 363 #ifdef HIF_LINUX_MMC_SCATTER_SUPPORT 364 365 #define MAX_SCATTER_REQUESTS 4 366 #define MAX_SCATTER_ENTRIES_PER_REQ 16 367 #define MAX_SCATTER_REQ_TRANSFER_SIZE (32*1024) 368 369 struct HIF_SCATTER_REQ_PRIV { 370 struct _HIF_SCATTER_REQ *hif_scatter_req; 371 struct hif_sdio_dev *device; /* this device */ 372 struct bus_request *busrequest; 373 /* scatter list for linux */ 374 struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ]; 375 }; 376 377 #define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0) 378 379 QDF_STATUS setup_hif_scatter_support(struct hif_sdio_dev *device, 380 struct HIF_DEVICE_SCATTER_SUPPORT_INFO *info); 381 void cleanup_hif_scatter_resources(struct hif_sdio_dev *device); 382 QDF_STATUS do_hif_read_write_scatter(struct hif_sdio_dev *device, 383 struct bus_request *busrequest); 384 385 #else /* HIF_LINUX_MMC_SCATTER_SUPPORT */ 386 setup_hif_scatter_support(struct hif_sdio_dev * device,struct HIF_DEVICE_SCATTER_SUPPORT_INFO * info)387 static inline QDF_STATUS setup_hif_scatter_support(struct hif_sdio_dev *device, 388 struct HIF_DEVICE_SCATTER_SUPPORT_INFO *info) 389 { 390 return QDF_STATUS_E_NOSUPPORT; 391 } 392 do_hif_read_write_scatter(struct hif_sdio_dev * device,struct bus_request * busrequest)393 static inline QDF_STATUS do_hif_read_write_scatter(struct hif_sdio_dev *device, 394 struct bus_request *busrequest) 395 { 396 return QDF_STATUS_E_NOSUPPORT; 397 } 398 399 #define cleanup_hif_scatter_resources(d) { } 400 401 #endif /* HIF_LINUX_MMC_SCATTER_SUPPORT */ 402 403 #define SDIO_SET_CMD52_ARG(arg, rw, func, raw, address, writedata) \ 404 ((arg) = (((rw) & 1) << 31) | \ 405 (((func) & 0x7) << 28) | \ 406 (((raw) & 1) << 27) | \ 407 (1 << 26) | \ 408 (((address) & 0x1FFFF) << 9) | \ 409 (1 << 8) | \ 410 ((writedata) & 0xFF)) 411 412 #define SDIO_SET_CMD52_READ_ARG(arg, func, address) \ 413 SDIO_SET_CMD52_ARG(arg, 0, (func), 0, address, 0x00) 414 #define SDIO_SET_CMD52_WRITE_ARG(arg, func, address, value) \ 415 SDIO_SET_CMD52_ARG(arg, 1, (func), 0, address, value) 416 417 void hif_sdio_quirk_force_drive_strength(struct hif_softc *ol_sc, 418 struct sdio_func *func); 419 void hif_sdio_quirk_write_cccr(struct hif_softc *ol_sc, struct sdio_func *func); 420 int hif_sdio_quirk_mod_strength(struct hif_softc *ol_sc, 421 struct sdio_func *func); 422 int hif_sdio_quirk_async_intr(struct hif_softc *ol_sc, struct sdio_func *func); 423 int hif_sdio_set_bus_speed(struct hif_softc *ol_sc, struct sdio_func *func); 424 int hif_sdio_set_bus_width(struct hif_softc *ol_sc, struct sdio_func *func); 425 QDF_STATUS hif_sdio_func_disable(struct hif_sdio_dev *device, 426 struct sdio_func *func, 427 bool reset); 428 QDF_STATUS reinit_sdio(struct hif_sdio_dev *device); 429 430 int func0_cmd52_write_byte(struct mmc_card *card, 431 unsigned int address, 432 unsigned char byte); 433 434 int func0_cmd52_read_byte(struct mmc_card *card, 435 unsigned int address, 436 unsigned char *byte); 437 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) 438 /** 439 * sdio_card_highspeed() - check if high speed supported 440 * @card: pointer to mmc card struct 441 * 442 * Return: non zero if card supports high speed. 443 */ sdio_card_highspeed(struct mmc_card * card)444 static inline int sdio_card_highspeed(struct mmc_card *card) 445 { 446 return mmc_card_highspeed(card); 447 } 448 #else sdio_card_highspeed(struct mmc_card * card)449 static inline int sdio_card_highspeed(struct mmc_card *card) 450 { 451 return mmc_card_hs(card); 452 } 453 #endif 454 455 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) 456 /** 457 * sdio_card_set_highspeed() - set high speed 458 * @card: pointer to mmc card struct 459 * 460 * Return: none. 461 */ sdio_card_set_highspeed(struct mmc_card * card)462 static inline void sdio_card_set_highspeed(struct mmc_card *card) 463 { 464 mmc_card_set_highspeed(card); 465 } 466 #else sdio_card_set_highspeed(struct mmc_card * card)467 static inline void sdio_card_set_highspeed(struct mmc_card *card) 468 { 469 } 470 #endif 471 472 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) 473 /** 474 * sdio_card_state() - set card state 475 * @card: pointer to mmc card struct 476 * 477 * Return: none. 478 */ sdio_card_state(struct mmc_card * card)479 static inline void sdio_card_state(struct mmc_card *card) 480 { 481 card->state &= ~MMC_STATE_HIGHSPEED; 482 } 483 #else sdio_card_state(struct mmc_card * card)484 static inline void sdio_card_state(struct mmc_card *card) 485 { 486 } 487 #endif 488 #endif /* _HIF_INTERNAL_H_ */ 489