Commit | Line | Data |
---|---|---|
bdcd8170 KV |
1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | |
3 | * | |
4 | * Permission to use, copy, modify, and/or distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | ||
17 | #ifndef HIF_H | |
18 | #define HIF_H | |
19 | ||
20 | #include "common.h" | |
21 | #include "core.h" | |
22 | ||
23 | #include <linux/scatterlist.h> | |
24 | ||
25 | #define BUS_REQUEST_MAX_NUM 64 | |
26 | #define HIF_MBOX_BLOCK_SIZE 128 | |
27 | #define HIF_MBOX0_BLOCK_SIZE 1 | |
28 | ||
29 | #define HIF_DMA_BUFFER_SIZE (32 * 1024) | |
30 | #define CMD53_FIXED_ADDRESS 1 | |
31 | #define CMD53_INCR_ADDRESS 2 | |
32 | ||
33 | #define MAX_SCATTER_REQUESTS 4 | |
34 | #define MAX_SCATTER_ENTRIES_PER_REQ 16 | |
35 | #define MAX_SCATTER_REQ_TRANSFER_SIZE (32 * 1024) | |
36 | ||
37 | #define MANUFACTURER_ID_AR6003_BASE 0x300 | |
38 | /* SDIO manufacturer ID and Codes */ | |
39 | #define MANUFACTURER_ID_ATH6KL_BASE_MASK 0xFF00 | |
40 | #define MANUFACTURER_CODE 0x271 /* Atheros */ | |
41 | ||
42 | /* Mailbox address in SDIO address space */ | |
43 | #define HIF_MBOX_BASE_ADDR 0x800 | |
44 | #define HIF_MBOX_WIDTH 0x800 | |
45 | ||
46 | #define HIF_MBOX_END_ADDR (HTC_MAILBOX_NUM_MAX * HIF_MBOX_WIDTH - 1) | |
47 | ||
48 | /* version 1 of the chip has only a 12K extended mbox range */ | |
49 | #define HIF_MBOX0_EXT_BASE_ADDR 0x4000 | |
50 | #define HIF_MBOX0_EXT_WIDTH (12*1024) | |
51 | ||
52 | /* GMBOX addresses */ | |
53 | #define HIF_GMBOX_BASE_ADDR 0x7000 | |
54 | #define HIF_GMBOX_WIDTH 0x4000 | |
55 | ||
56 | /* interrupt mode register */ | |
57 | #define CCCR_SDIO_IRQ_MODE_REG 0xF0 | |
58 | ||
59 | /* mode to enable special 4-bit interrupt assertion without clock */ | |
60 | #define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0) | |
61 | ||
2e1cb23c KV |
62 | /* HTC runs over mailbox 0 */ |
63 | #define HTC_MAILBOX 0 | |
64 | ||
65 | #define ATH6KL_TARGET_DEBUG_INTR_MASK 0x01 | |
66 | ||
67 | /* FIXME: are these duplicates with MAX_SCATTER_ values in hif.h? */ | |
68 | #define ATH6KL_SCATTER_ENTRIES_PER_REQ 16 | |
69 | #define ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER (16 * 1024) | |
70 | #define ATH6KL_SCATTER_REQS 4 | |
71 | ||
bdcd8170 KV |
72 | struct bus_request { |
73 | struct list_head list; | |
74 | ||
75 | /* request data */ | |
76 | u32 address; | |
77 | ||
78 | u8 *buffer; | |
79 | u32 length; | |
80 | u32 request; | |
81 | struct htc_packet *packet; | |
82 | int status; | |
83 | ||
84 | /* this is a scatter request */ | |
85 | struct hif_scatter_req *scat_req; | |
86 | }; | |
87 | ||
88 | /* direction of transfer (read/write) */ | |
89 | #define HIF_READ 0x00000001 | |
90 | #define HIF_WRITE 0x00000002 | |
91 | #define HIF_DIR_MASK (HIF_READ | HIF_WRITE) | |
92 | ||
93 | /* | |
94 | * emode - This indicates the whether the command is to be executed in a | |
95 | * blocking or non-blocking fashion (HIF_SYNCHRONOUS/ | |
96 | * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been | |
97 | * implemented using the asynchronous mode allowing the the bus | |
98 | * driver to indicate the completion of operation through the | |
99 | * registered callback routine. The requirement primarily comes | |
100 | * from the contexts these operations get called from (a driver's | |
101 | * transmit context or the ISR context in case of receive). | |
102 | * Support for both of these modes is essential. | |
103 | */ | |
104 | #define HIF_SYNCHRONOUS 0x00000010 | |
105 | #define HIF_ASYNCHRONOUS 0x00000020 | |
106 | #define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS) | |
107 | ||
108 | /* | |
109 | * dmode - An interface may support different kinds of commands based on | |
110 | * the tradeoff between the amount of data it can carry and the | |
111 | * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/ | |
112 | * HIF_BLOCK_BASIS). In case of latter, the data is rounded off | |
113 | * to the nearest block size by padding. The size of the block is | |
114 | * configurable at compile time using the HIF_BLOCK_SIZE and is | |
115 | * negotiated with the target during initialization after the | |
116 | * ATH6KL interrupts are enabled. | |
117 | */ | |
118 | #define HIF_BYTE_BASIS 0x00000040 | |
119 | #define HIF_BLOCK_BASIS 0x00000080 | |
120 | #define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS) | |
121 | ||
122 | /* | |
123 | * amode - This indicates if the address has to be incremented on ATH6KL | |
124 | * after every read/write operation (HIF?FIXED_ADDRESS/ | |
125 | * HIF_INCREMENTAL_ADDRESS). | |
126 | */ | |
127 | #define HIF_FIXED_ADDRESS 0x00000100 | |
128 | #define HIF_INCREMENTAL_ADDRESS 0x00000200 | |
129 | #define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS) | |
130 | ||
131 | #define HIF_WR_ASYNC_BYTE_INC \ | |
132 | (HIF_WRITE | HIF_ASYNCHRONOUS | \ | |
133 | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) | |
134 | ||
135 | #define HIF_WR_ASYNC_BLOCK_INC \ | |
136 | (HIF_WRITE | HIF_ASYNCHRONOUS | \ | |
137 | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) | |
138 | ||
139 | #define HIF_WR_SYNC_BYTE_FIX \ | |
140 | (HIF_WRITE | HIF_SYNCHRONOUS | \ | |
141 | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) | |
142 | ||
143 | #define HIF_WR_SYNC_BYTE_INC \ | |
144 | (HIF_WRITE | HIF_SYNCHRONOUS | \ | |
145 | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) | |
146 | ||
147 | #define HIF_WR_SYNC_BLOCK_INC \ | |
148 | (HIF_WRITE | HIF_SYNCHRONOUS | \ | |
149 | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) | |
150 | ||
151 | #define HIF_RD_SYNC_BYTE_INC \ | |
152 | (HIF_READ | HIF_SYNCHRONOUS | \ | |
153 | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) | |
154 | ||
155 | #define HIF_RD_SYNC_BYTE_FIX \ | |
156 | (HIF_READ | HIF_SYNCHRONOUS | \ | |
157 | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) | |
158 | ||
159 | #define HIF_RD_ASYNC_BLOCK_FIX \ | |
160 | (HIF_READ | HIF_ASYNCHRONOUS | \ | |
161 | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) | |
162 | ||
163 | #define HIF_RD_SYNC_BLOCK_FIX \ | |
164 | (HIF_READ | HIF_SYNCHRONOUS | \ | |
165 | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) | |
166 | ||
167 | struct hif_scatter_item { | |
168 | u8 *buf; | |
169 | int len; | |
170 | struct htc_packet *packet; | |
171 | }; | |
172 | ||
173 | struct hif_scatter_req { | |
174 | struct list_head list; | |
175 | /* address for the read/write operation */ | |
176 | u32 addr; | |
177 | ||
178 | /* request flags */ | |
179 | u32 req; | |
180 | ||
181 | /* total length of entire transfer */ | |
182 | u32 len; | |
183 | ||
4a005c3e VT |
184 | bool virt_scat; |
185 | ||
e041c7f9 | 186 | void (*complete) (struct htc_target *, struct hif_scatter_req *); |
bdcd8170 | 187 | int status; |
bdcd8170 KV |
188 | int scat_entries; |
189 | ||
d4df7890 VT |
190 | struct bus_request *busrequest; |
191 | struct scatterlist *sgentries; | |
bdcd8170 KV |
192 | |
193 | /* bounce buffer for upper layers to copy to/from */ | |
194 | u8 *virt_dma_buf; | |
195 | ||
196 | struct hif_scatter_item scat_list[1]; | |
197 | }; | |
198 | ||
2e1cb23c KV |
199 | struct ath6kl_irq_proc_registers { |
200 | u8 host_int_status; | |
201 | u8 cpu_int_status; | |
202 | u8 error_int_status; | |
203 | u8 counter_int_status; | |
204 | u8 mbox_frame; | |
205 | u8 rx_lkahd_valid; | |
206 | u8 host_int_status2; | |
207 | u8 gmbox_rx_avail; | |
208 | __le32 rx_lkahd[2]; | |
209 | __le32 rx_gmbox_lkahd_alias[2]; | |
210 | } __packed; | |
211 | ||
212 | struct ath6kl_irq_enable_reg { | |
213 | u8 int_status_en; | |
214 | u8 cpu_int_status_en; | |
215 | u8 err_int_status_en; | |
216 | u8 cntr_int_status_en; | |
217 | } __packed; | |
218 | ||
219 | struct ath6kl_device { | |
220 | spinlock_t lock; | |
221 | struct ath6kl_irq_proc_registers irq_proc_reg; | |
222 | struct ath6kl_irq_enable_reg irq_en_reg; | |
223 | struct htc_target *htc_cnxt; | |
224 | struct ath6kl *ar; | |
225 | }; | |
226 | ||
bdcd8170 KV |
227 | struct ath6kl_hif_ops { |
228 | int (*read_write_sync)(struct ath6kl *ar, u32 addr, u8 *buf, | |
229 | u32 len, u32 request); | |
230 | int (*write_async)(struct ath6kl *ar, u32 address, u8 *buffer, | |
231 | u32 length, u32 request, struct htc_packet *packet); | |
232 | ||
233 | void (*irq_enable)(struct ath6kl *ar); | |
234 | void (*irq_disable)(struct ath6kl *ar); | |
235 | ||
236 | struct hif_scatter_req *(*scatter_req_get)(struct ath6kl *ar); | |
237 | void (*scatter_req_add)(struct ath6kl *ar, | |
238 | struct hif_scatter_req *s_req); | |
50745af7 | 239 | int (*enable_scatter)(struct ath6kl *ar); |
f74a7361 VT |
240 | int (*scat_req_rw) (struct ath6kl *ar, |
241 | struct hif_scatter_req *scat_req); | |
bdcd8170 | 242 | void (*cleanup_scatter)(struct ath6kl *ar); |
abcb344b | 243 | int (*suspend)(struct ath6kl *ar); |
aa6cffc1 | 244 | int (*resume)(struct ath6kl *ar); |
b2e75698 KV |
245 | int (*power_on)(struct ath6kl *ar); |
246 | int (*power_off)(struct ath6kl *ar); | |
bdcd8170 KV |
247 | }; |
248 | ||
2e1cb23c KV |
249 | int ath6kl_hif_setup(struct ath6kl_device *dev); |
250 | int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev); | |
251 | int ath6kl_hif_mask_intrs(struct ath6kl_device *dev); | |
252 | int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, | |
253 | u32 *lk_ahd, int timeout); | |
254 | int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx); | |
255 | int ath6kl_hif_disable_intrs(struct ath6kl_device *dev); | |
256 | ||
257 | int ath6kl_hif_rw_comp_handler(void *context, int status); | |
258 | int ath6kl_hif_intr_bh_handler(struct ath6kl *ar); | |
259 | ||
260 | /* Scatter Function and Definitions */ | |
261 | int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev, | |
262 | struct hif_scatter_req *scat_req, bool read); | |
263 | ||
bdcd8170 | 264 | #endif |