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