Commit | Line | Data |
---|---|---|
bb9f8692 ZY |
1 | /* |
2 | * Intel Wireless Multicomm 3200 WiFi driver | |
3 | * | |
4 | * Copyright (C) 2009 Intel Corporation. All rights reserved. | |
5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * | |
10 | * * Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | |
12 | * * Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in | |
14 | * the documentation and/or other materials provided with the | |
15 | * distribution. | |
16 | * * Neither the name of Intel Corporation nor the names of its | |
17 | * contributors may be used to endorse or promote products derived | |
18 | * from this software without specific prior written permission. | |
19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
31 | * | |
32 | * | |
33 | * Intel Corporation <ilw@linux.intel.com> | |
34 | * Samuel Ortiz <samuel.ortiz@intel.com> | |
35 | * Zhu Yi <yi.zhu@intel.com> | |
36 | * | |
37 | */ | |
38 | ||
39 | #ifndef __IWM_H__ | |
40 | #define __IWM_H__ | |
41 | ||
42 | #include <linux/netdevice.h> | |
43 | #include <linux/wireless.h> | |
44 | #include <net/cfg80211.h> | |
45 | ||
46 | #include "debug.h" | |
47 | #include "hal.h" | |
48 | #include "umac.h" | |
49 | #include "lmac.h" | |
50 | #include "eeprom.h" | |
51 | ||
52 | #define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" | |
53 | #define IWM_AUTHOR "<ilw@linux.intel.com>" | |
54 | ||
bb9f8692 ZY |
55 | #define IWM_SRC_LMAC UMAC_HDI_IN_SOURCE_FHRX |
56 | #define IWM_SRC_UDMA UMAC_HDI_IN_SOURCE_UDMA | |
57 | #define IWM_SRC_UMAC UMAC_HDI_IN_SOURCE_FW | |
58 | #define IWM_SRC_NUM 3 | |
59 | ||
60 | #define IWM_POWER_INDEX_MIN 0 | |
61 | #define IWM_POWER_INDEX_MAX 5 | |
62 | #define IWM_POWER_INDEX_DEFAULT 3 | |
63 | ||
64 | struct iwm_conf { | |
65 | u32 sdio_ior_timeout; | |
fd2c7fe0 | 66 | unsigned long calib_map; |
d04bd628 | 67 | unsigned long expected_calib_map; |
e85498b2 SO |
68 | u8 ct_kill_entry; |
69 | u8 ct_kill_exit; | |
bb9f8692 ZY |
70 | bool reset_on_fatal_err; |
71 | bool auto_connect; | |
72 | bool wimax_not_present; | |
73 | bool enable_qos; | |
74 | u32 mode; | |
75 | ||
76 | u32 power_index; | |
77 | u32 frag_threshold; | |
78 | u32 rts_threshold; | |
79 | bool cts_to_self; | |
80 | ||
81 | u32 assoc_timeout; | |
82 | u32 roam_timeout; | |
83 | u32 wireless_mode; | |
bb9f8692 ZY |
84 | |
85 | u8 ibss_band; | |
86 | u8 ibss_channel; | |
87 | ||
88 | u8 mac_addr[ETH_ALEN]; | |
bb9f8692 ZY |
89 | }; |
90 | ||
91 | enum { | |
92 | COEX_MODE_SA = 1, | |
93 | COEX_MODE_XOR, | |
94 | COEX_MODE_CM, | |
95 | COEX_MODE_MAX, | |
96 | }; | |
97 | ||
98 | struct iwm_if_ops; | |
99 | struct iwm_wifi_cmd; | |
100 | ||
101 | struct pool_entry { | |
102 | int id; /* group id */ | |
103 | int sid; /* super group id */ | |
104 | int min_pages; /* min capacity in pages */ | |
105 | int max_pages; /* max capacity in pages */ | |
106 | int alloc_pages; /* allocated # of pages. incresed by driver */ | |
107 | int total_freed_pages; /* total freed # of pages. incresed by UMAC */ | |
108 | }; | |
109 | ||
110 | struct spool_entry { | |
111 | int id; | |
112 | int max_pages; | |
113 | int alloc_pages; | |
114 | }; | |
115 | ||
116 | struct iwm_tx_credit { | |
117 | spinlock_t lock; | |
118 | int pool_nr; | |
119 | unsigned long full_pools_map; /* bitmap for # of filled tx pools */ | |
120 | struct pool_entry pools[IWM_MACS_OUT_GROUPS]; | |
121 | struct spool_entry spools[IWM_MACS_OUT_SGROUPS]; | |
122 | }; | |
123 | ||
124 | struct iwm_notif { | |
125 | struct list_head pending; | |
126 | u32 cmd_id; | |
127 | void *cmd; | |
128 | u8 src; | |
129 | void *buf; | |
130 | unsigned long buf_size; | |
131 | }; | |
132 | ||
a7af530d SO |
133 | struct iwm_tid_info { |
134 | __le16 last_seq_num; | |
135 | bool stopped; | |
136 | struct mutex mutex; | |
137 | }; | |
138 | ||
bb9f8692 ZY |
139 | struct iwm_sta_info { |
140 | u8 addr[ETH_ALEN]; | |
141 | bool valid; | |
142 | bool qos; | |
143 | u8 color; | |
a7af530d | 144 | struct iwm_tid_info tid_info[IWM_UMAC_TID_NR]; |
bb9f8692 ZY |
145 | }; |
146 | ||
147 | struct iwm_tx_info { | |
148 | u8 sta; | |
149 | u8 color; | |
150 | u8 tid; | |
151 | }; | |
152 | ||
153 | struct iwm_rx_info { | |
154 | unsigned long rx_size; | |
155 | unsigned long rx_buf_size; | |
156 | }; | |
157 | ||
158 | #define IWM_NUM_KEYS 4 | |
159 | ||
160 | struct iwm_umac_key_hdr { | |
161 | u8 mac[ETH_ALEN]; | |
162 | u8 key_idx; | |
163 | u8 multicast; /* BCast encrypt & BCast decrypt of frames FROM mac */ | |
164 | } __attribute__ ((packed)); | |
165 | ||
166 | struct iwm_key { | |
167 | struct iwm_umac_key_hdr hdr; | |
13e0fe70 SO |
168 | u32 cipher; |
169 | u8 key[WLAN_MAX_KEY_LEN]; | |
170 | u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; | |
171 | int key_len; | |
172 | int seq_len; | |
bb9f8692 ZY |
173 | }; |
174 | ||
175 | #define IWM_RX_ID_HASH 0xff | |
176 | #define IWM_RX_ID_GET_HASH(id) ((id) % IWM_RX_ID_HASH) | |
177 | ||
178 | #define IWM_STA_TABLE_NUM 16 | |
179 | #define IWM_TX_LIST_SIZE 64 | |
180 | #define IWM_RX_LIST_SIZE 256 | |
181 | ||
182 | #define IWM_SCAN_ID_MAX 0xff | |
183 | ||
184 | #define IWM_STATUS_READY 0 | |
185 | #define IWM_STATUS_SCANNING 1 | |
186 | #define IWM_STATUS_SCAN_ABORTING 2 | |
de15fd31 | 187 | #define IWM_STATUS_SME_CONNECTING 3 |
bb9f8692 | 188 | #define IWM_STATUS_ASSOCIATED 4 |
d210176e | 189 | #define IWM_STATUS_RESETTING 5 |
bb9f8692 | 190 | |
bb9f8692 ZY |
191 | struct iwm_tx_queue { |
192 | int id; | |
193 | struct sk_buff_head queue; | |
a7af530d SO |
194 | struct sk_buff_head stopped_queue; |
195 | spinlock_t lock; | |
bb9f8692 ZY |
196 | struct workqueue_struct *wq; |
197 | struct work_struct worker; | |
198 | u8 concat_buf[IWM_HAL_CONCATENATE_BUF_SIZE]; | |
199 | int concat_count; | |
200 | u8 *concat_ptr; | |
201 | }; | |
202 | ||
203 | /* Queues 0 ~ 3 for AC data, 5 for iPAN */ | |
204 | #define IWM_TX_QUEUES 5 | |
205 | #define IWM_TX_DATA_QUEUES 4 | |
206 | #define IWM_TX_CMD_QUEUE 4 | |
207 | ||
208 | struct iwm_bss_info { | |
209 | struct list_head node; | |
210 | struct cfg80211_bss *cfg_bss; | |
211 | struct iwm_umac_notif_bss_info *bss; | |
212 | }; | |
213 | ||
214 | typedef int (*iwm_handler)(struct iwm_priv *priv, u8 *buf, | |
215 | unsigned long buf_size, struct iwm_wifi_cmd *cmd); | |
216 | ||
217 | #define IWM_WATCHDOG_PERIOD (6 * HZ) | |
218 | ||
219 | struct iwm_priv { | |
220 | struct wireless_dev *wdev; | |
221 | struct iwm_if_ops *bus_ops; | |
222 | ||
223 | struct iwm_conf conf; | |
224 | ||
225 | unsigned long status; | |
bb9f8692 ZY |
226 | |
227 | struct list_head pending_notif; | |
228 | wait_queue_head_t notif_queue; | |
229 | ||
230 | wait_queue_head_t nonwifi_queue; | |
231 | ||
232 | unsigned long calib_done_map; | |
233 | struct { | |
234 | u8 *buf; | |
235 | u32 size; | |
236 | } calib_res[CALIBRATION_CMD_NUM]; | |
237 | ||
238 | struct iwm_umac_profile *umac_profile; | |
239 | bool umac_profile_active; | |
240 | ||
241 | u8 bssid[ETH_ALEN]; | |
242 | u8 channel; | |
243 | u16 rate; | |
257862f3 | 244 | u32 txpower; |
bb9f8692 ZY |
245 | |
246 | struct iwm_sta_info sta_table[IWM_STA_TABLE_NUM]; | |
247 | struct list_head bss_list; | |
248 | ||
249 | void (*nonwifi_rx_handlers[UMAC_HDI_IN_OPCODE_NONWIFI_MAX]) | |
250 | (struct iwm_priv *priv, u8 *buf, unsigned long buf_size); | |
251 | ||
252 | const iwm_handler *umac_handlers; | |
253 | const iwm_handler *lmac_handlers; | |
254 | DECLARE_BITMAP(lmac_handler_map, LMAC_COMMAND_ID_NUM); | |
255 | DECLARE_BITMAP(umac_handler_map, LMAC_COMMAND_ID_NUM); | |
256 | DECLARE_BITMAP(udma_handler_map, LMAC_COMMAND_ID_NUM); | |
257 | ||
258 | struct list_head wifi_pending_cmd; | |
259 | struct list_head nonwifi_pending_cmd; | |
260 | u16 wifi_seq_num; | |
261 | u8 nonwifi_seq_num; | |
262 | spinlock_t cmd_lock; | |
263 | ||
264 | u32 core_enabled; | |
265 | ||
266 | u8 scan_id; | |
267 | struct cfg80211_scan_request *scan_request; | |
268 | ||
269 | struct sk_buff_head rx_list; | |
270 | struct list_head rx_tickets; | |
6c853da3 | 271 | struct list_head rx_packets[IWM_RX_ID_HASH + 1]; |
bb9f8692 ZY |
272 | struct workqueue_struct *rx_wq; |
273 | struct work_struct rx_worker; | |
274 | ||
275 | struct iwm_tx_credit tx_credit; | |
276 | struct iwm_tx_queue txq[IWM_TX_QUEUES]; | |
277 | ||
278 | struct iwm_key keys[IWM_NUM_KEYS]; | |
13e0fe70 | 279 | s8 default_key; |
bb9f8692 | 280 | |
a70742f1 SO |
281 | DECLARE_BITMAP(wifi_ntfy, WIFI_IF_NTFY_MAX); |
282 | wait_queue_head_t wifi_ntfy_queue; | |
283 | ||
bb9f8692 ZY |
284 | wait_queue_head_t mlme_queue; |
285 | ||
286 | struct iw_statistics wstats; | |
287 | struct delayed_work stats_request; | |
c7436273 | 288 | struct delayed_work disconnect; |
e85498b2 | 289 | struct delayed_work ct_kill_delay; |
bb9f8692 ZY |
290 | |
291 | struct iwm_debugfs dbg; | |
292 | ||
293 | u8 *eeprom; | |
294 | struct timer_list watchdog; | |
295 | struct work_struct reset_worker; | |
9829e1b5 | 296 | struct work_struct auth_retry_worker; |
68810c5d | 297 | struct mutex mutex; |
bb9f8692 | 298 | |
b68518fc ZY |
299 | u8 *req_ie; |
300 | int req_ie_len; | |
301 | u8 *resp_ie; | |
302 | int resp_ie_len; | |
303 | ||
04e715cd | 304 | struct iwm_fw_error_hdr *last_fw_err; |
5dc53163 SO |
305 | char umac_version[8]; |
306 | char lmac_version[8]; | |
04e715cd | 307 | |
bb9f8692 ZY |
308 | char private[0] __attribute__((__aligned__(NETDEV_ALIGN))); |
309 | }; | |
310 | ||
311 | static inline void *iwm_private(struct iwm_priv *iwm) | |
312 | { | |
313 | BUG_ON(!iwm); | |
314 | return &iwm->private; | |
315 | } | |
316 | ||
317 | #define hw_to_iwm(h) (h->iwm) | |
318 | #define iwm_to_dev(i) (wiphy_dev(i->wdev->wiphy)) | |
319 | #define iwm_to_wiphy(i) (i->wdev->wiphy) | |
320 | #define wiphy_to_iwm(w) (struct iwm_priv *)(wiphy_priv(w)) | |
321 | #define iwm_to_wdev(i) (i->wdev) | |
322 | #define wdev_to_iwm(w) (struct iwm_priv *)(wdev_priv(w)) | |
323 | #define iwm_to_ndev(i) (i->wdev->netdev) | |
324 | #define ndev_to_iwm(n) (wdev_to_iwm(n->ieee80211_ptr)) | |
325 | #define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb)) | |
326 | #define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb) | |
327 | ||
bb9f8692 ZY |
328 | void *iwm_if_alloc(int sizeof_bus, struct device *dev, |
329 | struct iwm_if_ops *if_ops); | |
330 | void iwm_if_free(struct iwm_priv *iwm); | |
d7e057dc ZY |
331 | int iwm_if_add(struct iwm_priv *iwm); |
332 | void iwm_if_remove(struct iwm_priv *iwm); | |
bb9f8692 ZY |
333 | int iwm_mode_to_nl80211_iftype(int mode); |
334 | int iwm_priv_init(struct iwm_priv *iwm); | |
8d96e796 | 335 | void iwm_priv_deinit(struct iwm_priv *iwm); |
bb9f8692 | 336 | void iwm_reset(struct iwm_priv *iwm); |
d210176e | 337 | void iwm_resetting(struct iwm_priv *iwm); |
bb9f8692 ZY |
338 | void iwm_tx_credit_init_pools(struct iwm_priv *iwm, |
339 | struct iwm_umac_notif_alive *alive); | |
340 | int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb); | |
341 | int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd, | |
342 | u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size); | |
343 | int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout); | |
344 | void iwm_init_default_profile(struct iwm_priv *iwm, | |
345 | struct iwm_umac_profile *profile); | |
346 | void iwm_link_on(struct iwm_priv *iwm); | |
347 | void iwm_link_off(struct iwm_priv *iwm); | |
348 | int iwm_up(struct iwm_priv *iwm); | |
349 | int iwm_down(struct iwm_priv *iwm); | |
350 | ||
351 | /* TX API */ | |
8585c2b8 | 352 | int iwm_tid_to_queue(u16 tid); |
bb9f8692 ZY |
353 | void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages); |
354 | void iwm_tx_worker(struct work_struct *work); | |
355 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | |
356 | ||
357 | /* RX API */ | |
358 | void iwm_rx_setup_handlers(struct iwm_priv *iwm); | |
359 | int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size); | |
360 | int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size, | |
361 | struct iwm_wifi_cmd *cmd); | |
362 | void iwm_rx_free(struct iwm_priv *iwm); | |
363 | ||
bb9f8692 | 364 | #endif |