Commit | Line | Data |
---|---|---|
a910e4a9 SP |
1 | /* |
2 | * Common private data for ST-Ericsson CW1200 drivers | |
3 | * | |
4 | * Copyright (c) 2010, ST-Ericsson | |
5 | * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no> | |
6 | * | |
7 | * Based on the mac80211 Prism54 code, which is | |
8 | * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> | |
9 | * | |
10 | * Based on the islsm (softmac prism54) driver, which is: | |
11 | * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. | |
12 | * | |
13 | * This program is free software; you can redistribute it and/or modify | |
14 | * it under the terms of the GNU General Public License version 2 as | |
15 | * published by the Free Software Foundation. | |
16 | */ | |
17 | ||
18 | #ifndef CW1200_H | |
19 | #define CW1200_H | |
20 | ||
21 | #include <linux/wait.h> | |
a910e4a9 SP |
22 | #include <linux/mutex.h> |
23 | #include <linux/workqueue.h> | |
24 | #include <net/mac80211.h> | |
25 | ||
26 | #include "queue.h" | |
27 | #include "wsm.h" | |
28 | #include "scan.h" | |
29 | #include "txrx.h" | |
30 | #include "pm.h" | |
31 | ||
32 | /* Forward declarations */ | |
911373cc | 33 | struct hwbus_ops; |
a910e4a9 SP |
34 | struct task_struct; |
35 | struct cw1200_debug_priv; | |
36 | struct firmware; | |
37 | ||
a910e4a9 SP |
38 | #define CW1200_MAX_CTRL_FRAME_LEN (0x1000) |
39 | ||
40 | #define CW1200_MAX_STA_IN_AP_MODE (5) | |
41 | #define CW1200_LINK_ID_AFTER_DTIM (CW1200_MAX_STA_IN_AP_MODE + 1) | |
42 | #define CW1200_LINK_ID_UAPSD (CW1200_MAX_STA_IN_AP_MODE + 2) | |
43 | #define CW1200_LINK_ID_MAX (CW1200_MAX_STA_IN_AP_MODE + 3) | |
44 | #define CW1200_MAX_REQUEUE_ATTEMPTS (5) | |
45 | ||
46 | #define CW1200_MAX_TID (8) | |
47 | ||
48 | #define CW1200_BLOCK_ACK_CNT (30) | |
49 | #define CW1200_BLOCK_ACK_THLD (800) | |
50 | #define CW1200_BLOCK_ACK_HIST (3) | |
51 | #define CW1200_BLOCK_ACK_INTERVAL (1 * HZ / CW1200_BLOCK_ACK_HIST) | |
52 | ||
53 | #define CW1200_JOIN_TIMEOUT (1 * HZ) | |
54 | #define CW1200_AUTH_TIMEOUT (5 * HZ) | |
55 | ||
56 | struct cw1200_ht_info { | |
57 | struct ieee80211_sta_ht_cap ht_cap; | |
58 | enum nl80211_channel_type channel_type; | |
59 | u16 operation_mode; | |
60 | }; | |
61 | ||
62 | /* Please keep order */ | |
63 | enum cw1200_join_status { | |
64 | CW1200_JOIN_STATUS_PASSIVE = 0, | |
65 | CW1200_JOIN_STATUS_MONITOR, | |
66 | CW1200_JOIN_STATUS_JOINING, | |
67 | CW1200_JOIN_STATUS_PRE_STA, | |
68 | CW1200_JOIN_STATUS_STA, | |
69 | CW1200_JOIN_STATUS_IBSS, | |
70 | CW1200_JOIN_STATUS_AP, | |
71 | }; | |
72 | ||
73 | enum cw1200_link_status { | |
74 | CW1200_LINK_OFF, | |
75 | CW1200_LINK_RESERVE, | |
76 | CW1200_LINK_SOFT, | |
77 | CW1200_LINK_HARD, | |
78 | CW1200_LINK_RESET, | |
79 | CW1200_LINK_RESET_REMAP, | |
80 | }; | |
81 | ||
82 | extern int cw1200_power_mode; | |
83 | extern const char * const cw1200_fw_types[]; | |
84 | ||
85 | struct cw1200_link_entry { | |
86 | unsigned long timestamp; | |
87 | enum cw1200_link_status status; | |
88 | enum cw1200_link_status prev_status; | |
89 | u8 mac[ETH_ALEN]; | |
90 | u8 buffered[CW1200_MAX_TID]; | |
91 | struct sk_buff_head rx_queue; | |
92 | }; | |
93 | ||
94 | struct cw1200_common { | |
95 | /* interfaces to the rest of the stack */ | |
96 | struct ieee80211_hw *hw; | |
97 | struct ieee80211_vif *vif; | |
98 | struct device *pdev; | |
99 | ||
100 | /* Statistics */ | |
101 | struct ieee80211_low_level_stats stats; | |
102 | ||
103 | /* Our macaddr */ | |
104 | u8 mac_addr[ETH_ALEN]; | |
105 | ||
106 | /* Hardware interface */ | |
911373cc SP |
107 | const struct hwbus_ops *hwbus_ops; |
108 | struct hwbus_priv *hwbus_priv; | |
a910e4a9 SP |
109 | |
110 | /* Hardware information */ | |
111 | enum { | |
112 | HIF_9000_SILICON_VERSATILE = 0, | |
113 | HIF_8601_VERSATILE, | |
114 | HIF_8601_SILICON, | |
115 | } hw_type; | |
116 | enum { | |
117 | CW1200_HW_REV_CUT10 = 10, | |
118 | CW1200_HW_REV_CUT11 = 11, | |
119 | CW1200_HW_REV_CUT20 = 20, | |
120 | CW1200_HW_REV_CUT22 = 22, | |
121 | CW1X60_HW_REV = 40, | |
122 | } hw_revision; | |
123 | int hw_refclk; | |
124 | bool hw_have_5ghz; | |
125 | const struct firmware *sdd; | |
126 | char *sdd_path; | |
127 | ||
128 | struct cw1200_debug_priv *debug; | |
129 | ||
130 | struct workqueue_struct *workqueue; | |
131 | struct mutex conf_mutex; | |
132 | ||
133 | struct cw1200_queue tx_queue[4]; | |
134 | struct cw1200_queue_stats tx_queue_stats; | |
135 | int tx_burst_idx; | |
136 | ||
137 | /* firmware/hardware info */ | |
138 | unsigned int tx_hdr_len; | |
139 | ||
140 | /* Radio data */ | |
141 | int output_power; | |
142 | ||
143 | /* BBP/MAC state */ | |
144 | struct ieee80211_rate *rates; | |
145 | struct ieee80211_rate *mcs_rates; | |
146 | struct ieee80211_channel *channel; | |
147 | struct wsm_edca_params edca; | |
148 | struct wsm_tx_queue_params tx_queue_params; | |
149 | struct wsm_mib_association_mode association_mode; | |
150 | struct wsm_set_bss_params bss_params; | |
151 | struct cw1200_ht_info ht_info; | |
152 | struct wsm_set_pm powersave_mode; | |
153 | struct wsm_set_pm firmware_ps_mode; | |
154 | int cqm_rssi_thold; | |
155 | unsigned cqm_rssi_hyst; | |
156 | bool cqm_use_rssi; | |
157 | int cqm_beacon_loss_count; | |
158 | int channel_switch_in_progress; | |
159 | wait_queue_head_t channel_switch_done; | |
160 | u8 long_frame_max_tx_count; | |
161 | u8 short_frame_max_tx_count; | |
162 | int mode; | |
163 | bool enable_beacon; | |
164 | int beacon_int; | |
165 | bool listening; | |
166 | struct wsm_rx_filter rx_filter; | |
167 | struct wsm_mib_multicast_filter multicast_filter; | |
168 | bool has_multicast_subscription; | |
169 | bool disable_beacon_filter; | |
170 | struct work_struct update_filtering_work; | |
171 | struct work_struct set_beacon_wakeup_period_work; | |
172 | ||
173 | u8 ba_rx_tid_mask; | |
174 | u8 ba_tx_tid_mask; | |
175 | ||
176 | struct cw1200_pm_state pm_state; | |
177 | ||
178 | struct wsm_p2p_ps_modeinfo p2p_ps_modeinfo; | |
179 | struct wsm_uapsd_info uapsd_info; | |
180 | bool setbssparams_done; | |
181 | bool bt_present; | |
182 | u8 conf_listen_interval; | |
183 | u32 listen_interval; | |
184 | u32 erp_info; | |
185 | u32 rts_threshold; | |
186 | ||
187 | /* BH */ | |
188 | atomic_t bh_rx; | |
189 | atomic_t bh_tx; | |
190 | atomic_t bh_term; | |
191 | atomic_t bh_suspend; | |
192 | ||
193 | struct workqueue_struct *bh_workqueue; | |
194 | struct work_struct bh_work; | |
195 | ||
196 | int bh_error; | |
197 | wait_queue_head_t bh_wq; | |
198 | wait_queue_head_t bh_evt_wq; | |
199 | u8 buf_id_tx; | |
200 | u8 buf_id_rx; | |
201 | u8 wsm_rx_seq; | |
202 | u8 wsm_tx_seq; | |
203 | int hw_bufs_used; | |
204 | bool powersave_enabled; | |
205 | bool device_can_sleep; | |
206 | ||
207 | /* Scan status */ | |
208 | struct cw1200_scan scan; | |
209 | /* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid | |
8b3e7be4 SP |
210 | * FW issue with sleeping/waking up. |
211 | */ | |
a910e4a9 SP |
212 | atomic_t recent_scan; |
213 | struct delayed_work clear_recent_scan_work; | |
214 | ||
215 | /* WSM */ | |
216 | struct wsm_startup_ind wsm_caps; | |
217 | struct mutex wsm_cmd_mux; | |
218 | struct wsm_buf wsm_cmd_buf; | |
219 | struct wsm_cmd wsm_cmd; | |
220 | wait_queue_head_t wsm_cmd_wq; | |
221 | wait_queue_head_t wsm_startup_done; | |
222 | int firmware_ready; | |
223 | atomic_t tx_lock; | |
224 | ||
225 | /* WSM debug */ | |
226 | int wsm_enable_wsm_dumps; | |
227 | ||
228 | /* WSM Join */ | |
229 | enum cw1200_join_status join_status; | |
230 | u32 pending_frame_id; | |
231 | bool join_pending; | |
232 | struct delayed_work join_timeout; | |
233 | struct work_struct unjoin_work; | |
234 | struct work_struct join_complete_work; | |
235 | int join_complete_status; | |
236 | int join_dtim_period; | |
237 | bool delayed_unjoin; | |
238 | ||
239 | /* TX/RX and security */ | |
240 | s8 wep_default_key_id; | |
241 | struct work_struct wep_key_work; | |
242 | u32 key_map; | |
243 | struct wsm_add_key keys[WSM_KEY_MAX_INDEX + 1]; | |
244 | ||
245 | /* AP powersave */ | |
246 | u32 link_id_map; | |
247 | struct cw1200_link_entry link_id_db[CW1200_MAX_STA_IN_AP_MODE]; | |
248 | struct work_struct link_id_work; | |
249 | struct delayed_work link_id_gc_work; | |
250 | u32 sta_asleep_mask; | |
251 | u32 pspoll_mask; | |
252 | bool aid0_bit_set; | |
253 | spinlock_t ps_state_lock; /* Protect power save state */ | |
254 | bool buffered_multicasts; | |
255 | bool tx_multicast; | |
256 | struct work_struct set_tim_work; | |
257 | struct work_struct set_cts_work; | |
258 | struct work_struct multicast_start_work; | |
259 | struct work_struct multicast_stop_work; | |
260 | struct timer_list mcast_timeout; | |
261 | ||
262 | /* WSM events and CQM implementation */ | |
263 | spinlock_t event_queue_lock; /* Protect event queue */ | |
264 | struct list_head event_queue; | |
265 | struct work_struct event_handler; | |
266 | ||
267 | struct delayed_work bss_loss_work; | |
268 | spinlock_t bss_loss_lock; /* Protect BSS loss state */ | |
269 | int bss_loss_state; | |
7258416c | 270 | u32 bss_loss_confirm_id; |
a910e4a9 SP |
271 | int delayed_link_loss; |
272 | struct work_struct bss_params_work; | |
273 | ||
274 | /* TX rate policy cache */ | |
275 | struct tx_policy_cache tx_policy_cache; | |
276 | struct work_struct tx_policy_upload_work; | |
277 | ||
278 | /* legacy PS mode switch in suspend */ | |
279 | int ps_mode_switch_in_progress; | |
280 | wait_queue_head_t ps_mode_switch_done; | |
281 | ||
282 | /* Workaround for WFD testcase 6.1.10*/ | |
283 | struct work_struct linkid_reset_work; | |
284 | u8 action_frame_sa[ETH_ALEN]; | |
285 | u8 action_linkid; | |
a910e4a9 SP |
286 | }; |
287 | ||
288 | struct cw1200_sta_priv { | |
289 | int link_id; | |
290 | }; | |
291 | ||
292 | /* interfaces for the drivers */ | |
911373cc SP |
293 | int cw1200_core_probe(const struct hwbus_ops *hwbus_ops, |
294 | struct hwbus_priv *hwbus, | |
a910e4a9 SP |
295 | struct device *pdev, |
296 | struct cw1200_common **pself, | |
297 | int ref_clk, const u8 *macaddr, | |
298 | const char *sdd_path, bool have_5ghz); | |
299 | void cw1200_core_release(struct cw1200_common *self); | |
300 | ||
301 | #define FWLOAD_BLOCK_SIZE (1024) | |
302 | ||
303 | static inline int cw1200_is_ht(const struct cw1200_ht_info *ht_info) | |
304 | { | |
305 | return ht_info->channel_type != NL80211_CHAN_NO_HT; | |
306 | } | |
307 | ||
308 | static inline int cw1200_ht_greenfield(const struct cw1200_ht_info *ht_info) | |
309 | { | |
310 | return cw1200_is_ht(ht_info) && | |
311 | (ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && | |
312 | !(ht_info->operation_mode & | |
313 | IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | |
314 | } | |
315 | ||
316 | static inline int cw1200_ht_ampdu_density(const struct cw1200_ht_info *ht_info) | |
317 | { | |
318 | if (!cw1200_is_ht(ht_info)) | |
319 | return 0; | |
320 | return ht_info->ht_cap.ampdu_density; | |
321 | } | |
322 | ||
323 | #endif /* CW1200_H */ |