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 | ||
d60e8ab6 KV |
72 | #define ATH6KL_HIF_COMMUNICATION_TIMEOUT 1000 |
73 | ||
bdcd8170 KV |
74 | struct bus_request { |
75 | struct list_head list; | |
76 | ||
77 | /* request data */ | |
78 | u32 address; | |
79 | ||
80 | u8 *buffer; | |
81 | u32 length; | |
82 | u32 request; | |
83 | struct htc_packet *packet; | |
84 | int status; | |
85 | ||
86 | /* this is a scatter request */ | |
87 | struct hif_scatter_req *scat_req; | |
88 | }; | |
89 | ||
90 | /* direction of transfer (read/write) */ | |
91 | #define HIF_READ 0x00000001 | |
92 | #define HIF_WRITE 0x00000002 | |
93 | #define HIF_DIR_MASK (HIF_READ | HIF_WRITE) | |
94 | ||
95 | /* | |
96 | * emode - This indicates the whether the command is to be executed in a | |
97 | * blocking or non-blocking fashion (HIF_SYNCHRONOUS/ | |
98 | * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been | |
99 | * implemented using the asynchronous mode allowing the the bus | |
100 | * driver to indicate the completion of operation through the | |
101 | * registered callback routine. The requirement primarily comes | |
102 | * from the contexts these operations get called from (a driver's | |
103 | * transmit context or the ISR context in case of receive). | |
104 | * Support for both of these modes is essential. | |
105 | */ | |
106 | #define HIF_SYNCHRONOUS 0x00000010 | |
107 | #define HIF_ASYNCHRONOUS 0x00000020 | |
108 | #define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS) | |
109 | ||
110 | /* | |
111 | * dmode - An interface may support different kinds of commands based on | |
112 | * the tradeoff between the amount of data it can carry and the | |
113 | * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/ | |
114 | * HIF_BLOCK_BASIS). In case of latter, the data is rounded off | |
115 | * to the nearest block size by padding. The size of the block is | |
116 | * configurable at compile time using the HIF_BLOCK_SIZE and is | |
117 | * negotiated with the target during initialization after the | |
118 | * ATH6KL interrupts are enabled. | |
119 | */ | |
120 | #define HIF_BYTE_BASIS 0x00000040 | |
121 | #define HIF_BLOCK_BASIS 0x00000080 | |
122 | #define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS) | |
123 | ||
124 | /* | |
125 | * amode - This indicates if the address has to be incremented on ATH6KL | |
126 | * after every read/write operation (HIF?FIXED_ADDRESS/ | |
127 | * HIF_INCREMENTAL_ADDRESS). | |
128 | */ | |
129 | #define HIF_FIXED_ADDRESS 0x00000100 | |
130 | #define HIF_INCREMENTAL_ADDRESS 0x00000200 | |
131 | #define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS) | |
132 | ||
133 | #define HIF_WR_ASYNC_BYTE_INC \ | |
134 | (HIF_WRITE | HIF_ASYNCHRONOUS | \ | |
135 | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) | |
136 | ||
137 | #define HIF_WR_ASYNC_BLOCK_INC \ | |
138 | (HIF_WRITE | HIF_ASYNCHRONOUS | \ | |
139 | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) | |
140 | ||
141 | #define HIF_WR_SYNC_BYTE_FIX \ | |
142 | (HIF_WRITE | HIF_SYNCHRONOUS | \ | |
143 | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) | |
144 | ||
145 | #define HIF_WR_SYNC_BYTE_INC \ | |
146 | (HIF_WRITE | HIF_SYNCHRONOUS | \ | |
147 | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) | |
148 | ||
149 | #define HIF_WR_SYNC_BLOCK_INC \ | |
150 | (HIF_WRITE | HIF_SYNCHRONOUS | \ | |
151 | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) | |
152 | ||
153 | #define HIF_RD_SYNC_BYTE_INC \ | |
154 | (HIF_READ | HIF_SYNCHRONOUS | \ | |
155 | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) | |
156 | ||
157 | #define HIF_RD_SYNC_BYTE_FIX \ | |
158 | (HIF_READ | HIF_SYNCHRONOUS | \ | |
159 | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) | |
160 | ||
161 | #define HIF_RD_ASYNC_BLOCK_FIX \ | |
162 | (HIF_READ | HIF_ASYNCHRONOUS | \ | |
163 | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) | |
164 | ||
165 | #define HIF_RD_SYNC_BLOCK_FIX \ | |
166 | (HIF_READ | HIF_SYNCHRONOUS | \ | |
167 | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) | |
168 | ||
169 | struct hif_scatter_item { | |
170 | u8 *buf; | |
171 | int len; | |
172 | struct htc_packet *packet; | |
173 | }; | |
174 | ||
175 | struct hif_scatter_req { | |
176 | struct list_head list; | |
177 | /* address for the read/write operation */ | |
178 | u32 addr; | |
179 | ||
180 | /* request flags */ | |
181 | u32 req; | |
182 | ||
183 | /* total length of entire transfer */ | |
184 | u32 len; | |
185 | ||
4a005c3e VT |
186 | bool virt_scat; |
187 | ||
e041c7f9 | 188 | void (*complete) (struct htc_target *, struct hif_scatter_req *); |
bdcd8170 | 189 | int status; |
bdcd8170 KV |
190 | int scat_entries; |
191 | ||
d4df7890 VT |
192 | struct bus_request *busrequest; |
193 | struct scatterlist *sgentries; | |
bdcd8170 KV |
194 | |
195 | /* bounce buffer for upper layers to copy to/from */ | |
196 | u8 *virt_dma_buf; | |
197 | ||
198 | struct hif_scatter_item scat_list[1]; | |
199 | }; | |
200 | ||
2e1cb23c KV |
201 | struct ath6kl_irq_proc_registers { |
202 | u8 host_int_status; | |
203 | u8 cpu_int_status; | |
204 | u8 error_int_status; | |
205 | u8 counter_int_status; | |
206 | u8 mbox_frame; | |
207 | u8 rx_lkahd_valid; | |
208 | u8 host_int_status2; | |
209 | u8 gmbox_rx_avail; | |
210 | __le32 rx_lkahd[2]; | |
211 | __le32 rx_gmbox_lkahd_alias[2]; | |
212 | } __packed; | |
213 | ||
214 | struct ath6kl_irq_enable_reg { | |
215 | u8 int_status_en; | |
216 | u8 cpu_int_status_en; | |
217 | u8 err_int_status_en; | |
218 | u8 cntr_int_status_en; | |
219 | } __packed; | |
220 | ||
221 | struct ath6kl_device { | |
222 | spinlock_t lock; | |
223 | struct ath6kl_irq_proc_registers irq_proc_reg; | |
224 | struct ath6kl_irq_enable_reg irq_en_reg; | |
225 | struct htc_target *htc_cnxt; | |
226 | struct ath6kl *ar; | |
227 | }; | |
228 | ||
bdcd8170 KV |
229 | struct ath6kl_hif_ops { |
230 | int (*read_write_sync)(struct ath6kl *ar, u32 addr, u8 *buf, | |
231 | u32 len, u32 request); | |
232 | int (*write_async)(struct ath6kl *ar, u32 address, u8 *buffer, | |
233 | u32 length, u32 request, struct htc_packet *packet); | |
234 | ||
235 | void (*irq_enable)(struct ath6kl *ar); | |
236 | void (*irq_disable)(struct ath6kl *ar); | |
237 | ||
238 | struct hif_scatter_req *(*scatter_req_get)(struct ath6kl *ar); | |
239 | void (*scatter_req_add)(struct ath6kl *ar, | |
240 | struct hif_scatter_req *s_req); | |
50745af7 | 241 | int (*enable_scatter)(struct ath6kl *ar); |
f74a7361 VT |
242 | int (*scat_req_rw) (struct ath6kl *ar, |
243 | struct hif_scatter_req *scat_req); | |
bdcd8170 | 244 | void (*cleanup_scatter)(struct ath6kl *ar); |
0f60e9f4 | 245 | int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow); |
aa6cffc1 | 246 | int (*resume)(struct ath6kl *ar); |
b2e75698 KV |
247 | int (*power_on)(struct ath6kl *ar); |
248 | int (*power_off)(struct ath6kl *ar); | |
32a07e44 | 249 | void (*stop)(struct ath6kl *ar); |
bdcd8170 KV |
250 | }; |
251 | ||
2e1cb23c KV |
252 | int ath6kl_hif_setup(struct ath6kl_device *dev); |
253 | int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev); | |
254 | int ath6kl_hif_mask_intrs(struct ath6kl_device *dev); | |
255 | int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, | |
256 | u32 *lk_ahd, int timeout); | |
257 | int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx); | |
258 | int ath6kl_hif_disable_intrs(struct ath6kl_device *dev); | |
259 | ||
260 | int ath6kl_hif_rw_comp_handler(void *context, int status); | |
261 | int ath6kl_hif_intr_bh_handler(struct ath6kl *ar); | |
262 | ||
263 | /* Scatter Function and Definitions */ | |
264 | int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev, | |
265 | struct hif_scatter_req *scat_req, bool read); | |
266 | ||
bdcd8170 | 267 | #endif |