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