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