blob: 6770dcd6b15ff598e9b53a0e60a3a7f48bfca460 [file] [log] [blame]
pengcheng chen - Sun Microsystems - Beijing China9f758ca2009-03-20 09:05:19 +08001/*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6/*
7 * Copyright (c) 2003
8 * Daan Vreeken <Danovitsch@Vitsch.net>. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Daan Vreeken.
21 * 4. Neither the name of the author nor the names of any co-contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY DAAN VREEKEN AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35 * THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
38
39#ifndef _ATU_H
40#define _ATU_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46enum atu_radio_type {
47 RadioRFMD,
48 RadioRFMD2958,
49 RadioRFMD2958_SMC,
50 RadioIntersil,
51 AT76C503_i3863,
52 AT76C503_RFMD_ACC,
53 AT76C505_RFMD
54};
55
56struct atu_dev_type {
57 uint16_t atu_vid;
58 uint16_t atu_pid;
59 enum atu_radio_type atu_radio;
60 uint16_t atu_quirk;
61};
62
63struct atu_firmware {
64 enum atu_radio_type atur_type;
65 uint8_t *atur_int;
66 uint8_t *atur_ext;
67 uint_t atur_int_size;
68 uint_t atur_ext_size;
69 uint8_t max_rssi;
70};
71
72struct atu_softc {
73 struct ieee80211com sc_ic;
74
75 char sc_name[16];
76 uint32_t sc_flags;
77 enum atu_radio_type sc_radio;
78 uint16_t sc_quirk;
79
80 dev_info_t *sc_dip;
81 usb_client_dev_data_t *sc_udev;
82 usb_pipe_handle_t sc_rx_pipe;
83 usb_pipe_handle_t sc_tx_pipe;
84
85 kmutex_t sc_genlock;
86 kmutex_t sc_txlock;
87 kmutex_t sc_rxlock;
88
89 boolean_t sc_need_sched;
90 int tx_queued;
91 int rx_queued;
92
93 uint32_t sc_tx_nobuf;
94 uint32_t sc_rx_nobuf;
95 uint32_t sc_rx_err;
96
97 timeout_id_t sc_scan_timer;
98
99 int (*sc_newstate)(struct ieee80211com *,
100 enum ieee80211_state, int);
101};
102
103#define ATU_FLAG_RUNNING (1<<0)
104#define ATU_FLAG_REATTACH (1<<1)
105#define ATU_FLAG_RADIO_ON (1<<2)
106
107#define ATU_RUNNING(sc) ((sc)->sc_flags & ATU_FLAG_RUNNING)
108#define ATU_REATTACH(sc) ((sc)->sc_flags & ATU_FLAG_REATTACH)
109#define ATU_RADIO_ON(sc) ((sc)->sc_flags & ATU_FLAG_RADIO_ON)
110
111#define ATU_LOCK(sc) mutex_enter(&(sc)->sc_genlock)
112#define ATU_UNLOCK(sc) mutex_exit(&(sc)->sc_genlock)
113
114#define ATU_RX_LIST_CNT 1
115#define ATU_TX_LIST_CNT 8
116#define ATU_MIN_FRAMELEN sizeof (struct ieee80211_frame_min)
117
118#define ATU_RX_BUFSZ \
119 (ATU_RX_HDRLEN + \
120 sizeof (struct ieee80211_frame_addr4) + \
121 2312 + 4)
122#define ATU_TX_BUFSZ \
123 (ATU_TX_HDRLEN + \
124 sizeof (struct ieee80211_frame_addr4) + 2312)
125
126#define ATU_DEF_CHAN 10
127#define ATU_DEF_TX_RATE 3
128#define ATU_JOIN_TIMEOUT 2000
129
130#define ATU_QUIRK_NONE 0x0000
131#define ATU_QUIRK_NO_REMAP 0x0001
132#define ATU_QUIRK_FW_DELAY 0x0002
133
134#define ATU_ENC_NONE 0
135#define ATU_ENC_WEP40 1
136#define ATU_ENC_WEP104 2
137
138#define ATU_MODE_IBSS 1
139#define ATU_MODE_STA 2
140
141#define ATU_POWER_ACTIVE 1
142#define ATU_POWER_SAVE 2
143#define ATU_POWER_SMART 3
144
145#define ATU_PREAMBLE_LONG 0
146#define ATU_PREAMBLE_SHORT 1
147
148/* AT76c503 operating modes */
149#define ATU_DEV_UNKNOWN 0x00
150#define ATU_DEV_READY 0x01
151#define ATU_DEV_CONFIG 0x02
152#define ATU_DEV_DFU 0x03
153#define ATU_DEV_STAGE2 0x04
154
155/* AT76c503 commands */
156#define CMD_SET_MIB 0x01
157#define CMD_START_SCAN 0x03
158#define CMD_JOIN 0x04
159#define CMD_START_IBSS 0x05
160#define CMD_RADIO 0x06
161#define CMD_RADIO_ON 0x06
162#define CMD_RADIO_OFF 0x07
163#define CMD_STARTUP 0x0b
164
165/* AT76c503 wait status */
166#define STATUS_IDLE 0x00
167#define STATUS_COMPLETE 0x01
168#define STATUS_UNKNOWN 0x02
169#define STATUS_INVALID_PARAMETER 0x03
170#define STATUS_FUNCTION_NOT_SUPPORTED 0x04
171#define STATUS_TIME_OUT 0x07
172#define STATUS_IN_PROGRESS 0x08
173#define STATUS_HOST_FAILURE 0xff
174#define STATUS_SCAN_FAILED 0xf0
175
176/* Name Type Size Index */
177#define MIB_LOCAL 0x01
178#define MIB_LOCAL_BEACON_ENABLE MIB_LOCAL, 1, 2
179#define MIB_LOCAL_AUTO_RATE_FALLBACK MIB_LOCAL, 1, 3
180#define MIB_LOCAL_SSID_SIZE MIB_LOCAL, 1, 5
181#define MIB_LOCAL_PREAMBLE MIB_LOCAL, 1, 9
182#define MIB_MAC_ADDR 0x02
183#define MIB_MAC_ADDR_STA MIB_MAC_ADDR, 6, 0
184#define MIB_MAC 0x03
185#define MIB_MAC_FRAG MIB_MAC, 2, 8
186#define MIB_MAC_RTS MIB_MAC, 2, 10
187#define MIB_MAC_DESIRED_SSID MIB_MAC, 32, 28
188#define MIB_MAC_MGMT 0x05
189#define MIB_MAC_MGMT_BEACON_PERIOD MIB_MAC_MGMT, 2, 0
190#define MIB_MAC_MGMT_CURRENT_BSSID MIB_MAC_MGMT, 6, 14
191#define MIB_MAC_MGMT_CURRENT_ESSID MIB_MAC_MGMT, 32, 20
192#define MIB_MAC_MGMT_POWER_MODE MIB_MAC_MGMT, 1, 53
193#define MIB_MAC_MGMT_IBSS_CHANGE MIB_MAC_MGMT, 1, 54
194#define MIB_MAC_WEP 0x06
195#define MIB_MAC_WEP_PRIVACY_INVOKED MIB_MAC_WEP, 1, 0
196#define MIB_MAC_WEP_KEY_ID MIB_MAC_WEP, 1, 1
197#define MIB_MAC_WEP_ICV_ERROR_COUNT MIB_MAC_WEP, 4, 4
198#define MIB_MAC_WEP_EXCLUDED_COUNT MIB_MAC_WEP, 4, 8
199#define MIB_MAC_WEP_KEYS(nr) MIB_MAC_WEP, 13, 12+(nr)*13
200#define MIB_MAC_WEP_ENCR_LEVEL MIB_MAC_WEP, 1, 64
201#define MIB_PHY 0x07
202#define MIB_PHY_CHANNEL MIB_PHY, 1, 20
203#define MIB_PHY_REG_DOMAIN MIB_PHY, 1, 23
204#define MIB_FW_VERSION 0x08
205#define MIB_DOMAIN 0x09
206#define MIB_DOMAIN_POWER_LEVELS MIB_DOMAIN, 14, 0
207#define MIB_DOMAIN_CHANNELS MIB_DOMAIN, 14, 14
208
209/* USB request types */
210#define ATU_CLASS_IF_IN \
211 (USB_DEV_REQ_DEV_TO_HOST | \
212 USB_DEV_REQ_TYPE_CLASS | \
213 USB_DEV_REQ_RCPT_IF)
214
215#define ATU_VENDOR_IF_IN \
216 (USB_DEV_REQ_DEV_TO_HOST | \
217 USB_DEV_REQ_TYPE_VENDOR | \
218 USB_DEV_REQ_RCPT_IF)
219
220#define ATU_VENDOR_DEV_OUT \
221 (USB_DEV_REQ_HOST_TO_DEV | \
222 USB_DEV_REQ_TYPE_VENDOR | \
223 USB_DEV_REQ_RCPT_DEV)
224
225#define ATU_CLASS_IF_OUT \
226 (USB_DEV_REQ_HOST_TO_DEV | \
227 USB_DEV_REQ_TYPE_CLASS | \
228 USB_DEV_REQ_RCPT_IF)
229
230#define ATU_VENDOR_IF_OUT \
231 (USB_DEV_REQ_HOST_TO_DEV | \
232 USB_DEV_REQ_TYPE_VENDOR | \
233 USB_DEV_REQ_RCPT_IF)
234
235/* standard DFU commands */
236#define DFU_DNLOAD ATU_CLASS_IF_OUT, 0x01
237#define DFU_GETSTATUS ATU_CLASS_IF_IN, 0x03
238#define DFU_GETSTATE ATU_CLASS_IF_IN, 0x05
239#define DFU_REMAP ATU_VENDOR_IF_OUT, 0x0a
240
241/* DFU states */
242#define DFUState_AppIdle 0
243#define DFUState_AppDetach 1
244#define DFUState_DFUIdle 2
245#define DFUState_DnLoadSync 3
246#define DFUState_DnLoadBusy 4
247#define DFUState_DnLoadIdle 5
248#define DFUState_ManifestSync 6
249#define DFUState_Manifest 7
250#define DFUState_ManifestWait 8
251#define DFUState_UploadIdle 9
252#define DFUState_DFUError 10
253#define DFU_MaxBlockSize 1024
254
255#pragma pack(1)
256/* AT76c503 command header */
257struct atu_cmd {
258 uint8_t Cmd;
259 uint8_t Reserved;
260 uint16_t Size;
261};
262
263/* CMD_SET_MIB command (0x01) */
264struct atu_cmd_set_mib {
265 /* AT76c503 command header */
266 uint8_t AtCmd;
267 uint8_t AtReserved;
268 uint16_t AtSize;
269 /* MIB header */
270 uint8_t MIBType;
271 uint8_t MIBSize;
272 uint8_t MIBIndex;
273 uint8_t MIBReserved;
274 /* MIB data */
275 uint8_t data[72];
276};
277
278/* CMD_STARTUP command (0x0b) */
279struct atu_cmd_card_config {
280 uint8_t Cmd;
281 uint8_t Reserved;
282 uint16_t Size;
283
284 uint8_t ExcludeUnencrypted;
285 uint8_t PromiscuousMode;
286 uint8_t ShortRetryLimit;
287 uint8_t EncryptionType;
288 uint16_t RTS_Threshold;
289 uint16_t FragThreshold;
290 uint8_t BasicRateSet[4];
291 uint8_t AutoRateFallback;
292 uint8_t Channel;
293 uint8_t PrivacyInvoked;
294 uint8_t WEP_DefaultKeyID;
295 uint8_t SSID[IEEE80211_NWID_LEN];
296 uint8_t WEP_DefaultKey[4][13];
297 uint8_t SSID_Len;
298 uint8_t ShortPreamble;
299 uint16_t BeaconPeriod;
300};
301
302/* CMD_SCAN command (0x03) */
303struct atu_cmd_do_scan {
304 uint8_t Cmd;
305 uint8_t Reserved;
306 uint16_t Size;
307
308 uint8_t BSSID[IEEE80211_ADDR_LEN];
309 uint8_t SSID[IEEE80211_NWID_LEN];
310 uint8_t ScanType;
311 uint8_t Channel;
312 uint16_t ProbeDelay;
313 uint16_t MinChannelTime;
314 uint16_t MaxChannelTime;
315 uint8_t SSID_Len;
316 uint8_t InternationalScan;
317};
318#define ATU_SCAN_ACTIVE 0x00
319#define ATU_SCAN_PASSIVE 0x01
320
321/* CMD_JOIN command (0x04) */
322struct atu_cmd_join {
323 uint8_t Cmd;
324 uint8_t Reserved;
325 uint16_t Size;
326
327 uint8_t bssid[IEEE80211_ADDR_LEN];
328 uint8_t essid[32];
329 uint8_t bss_type;
330 uint8_t channel;
331 uint16_t timeout;
332 uint8_t essid_size;
333 uint8_t reserved;
334};
335
336/* CMD_START_IBSS (0x05) */
337struct atu_cmd_start_ibss {
338 uint8_t Cmd;
339 uint8_t Reserved;
340 uint16_t Size;
341
342 uint8_t BSSID[IEEE80211_ADDR_LEN];
343 uint8_t SSID[32];
344 uint8_t BSSType;
345 uint8_t Channel;
346 uint8_t SSIDSize;
347 uint8_t Res[3];
348};
349
350/*
351 * The At76c503 adapters come with different types of radios on them.
352 * At this moment the driver supports adapters with RFMD and Intersil radios.
353 */
354
355/* The config structure of an RFMD radio */
356struct atu_rfmd_conf {
357 uint8_t CR20[14];
358 uint8_t CR21[14];
359 uint8_t BB_CR[14];
360 uint8_t PidVid[4];
361 uint8_t MACAddr[IEEE80211_ADDR_LEN];
362 uint8_t RegulatoryDomain;
363 uint8_t LowPowerValues[14];
364 uint8_t NormalPowerValues[14];
365 uint8_t Reserved[3];
366 /* then we have 84 bytes, somehow Windows reads 95?? */
367 uint8_t Rest[11];
368};
369
370/* The config structure of an Intersil radio */
371struct atu_intersil_conf {
372 uint8_t MACAddr[IEEE80211_ADDR_LEN];
373 /* From the HFA3861B manual : */
374 /* Manual TX power control (7bit : -64 to 63) */
375 uint8_t CR31[14];
376 /* TX power measurement */
377 uint8_t CR58[14];
378 uint8_t PidVid[4];
379 uint8_t RegulatoryDomain;
380 uint8_t Reserved[1];
381};
382
383struct atu_rx_hdr {
384 uint16_t length;
385 uint8_t rx_rate;
386 uint8_t newbss;
387 uint8_t fragmentation;
388 uint8_t rssi;
389 uint8_t link_quality;
390 uint8_t noise_level;
391 uint32_t rx_time;
392};
393#define ATU_RX_HDRLEN sizeof (struct atu_rx_hdr)
394
395struct atu_tx_hdr {
396 uint16_t length;
397 uint8_t tx_rate;
398 uint8_t padding;
399 uint8_t reserved[4];
400};
401#define ATU_TX_HDRLEN sizeof (struct atu_tx_hdr)
402#pragma pack()
403
404static struct atu_dev_type atu_dev_table[] = {
405 { 0x0506, 0x0a01, RadioRFMD, ATU_QUIRK_NONE },
406 { 0x07b8, 0xb000, RadioRFMD, ATU_QUIRK_NONE },
407 { 0x083a, 0x3501, AT76C503_RFMD_ACC, ATU_QUIRK_NONE },
408 { 0x04a5, 0x9000, RadioIntersil, ATU_QUIRK_NONE },
409 { 0x04a5, 0x9001, RadioRFMD, ATU_QUIRK_NONE },
410 { 0x1668, 0x7605, RadioRFMD, ATU_QUIRK_NONE },
411 { 0x05dd, 0xff31, RadioIntersil, ATU_QUIRK_NONE },
412 { 0x12fd, 0x1001, RadioRFMD2958, ATU_QUIRK_NONE },
413 { 0x069a, 0x0821, RadioIntersil, ATU_QUIRK_NONE },
414 { 0x069a, 0x0320, RadioIntersil, ATU_QUIRK_NONE },
415 { 0x069a, 0x0321, RadioRFMD, ATU_QUIRK_NONE },
416 { 0x03eb, 0x7603, RadioIntersil, ATU_QUIRK_NONE },
417 { 0x03eb, 0x7604, AT76C503_i3863, ATU_QUIRK_NONE },
418 { 0x03eb, 0x7605, RadioRFMD, ATU_QUIRK_NONE },
419 { 0x03eb, 0x7606, AT76C505_RFMD, ATU_QUIRK_NONE },
420 { 0x03eb, 0x7613, RadioRFMD2958, ATU_QUIRK_NONE },
421 { 0x03eb, 0x7614, RadioRFMD2958_SMC,
422 ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
423 { 0x03eb, 0x7617, RadioRFMD2958_SMC,
424 ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
425 { 0x03eb, 0x3301, RadioRFMD, ATU_QUIRK_NONE },
426 { 0x050d, 0x0050, RadioRFMD, ATU_QUIRK_NONE },
427 { 0x0d8e, 0x7100, RadioIntersil, ATU_QUIRK_NONE },
428 { 0x0d8e, 0x7110, RadioIntersil, ATU_QUIRK_NONE },
429 { 0x049f, 0x0032, RadioRFMD, ATU_QUIRK_NONE },
430 { 0x07aa, 0x7613, RadioRFMD2958, ATU_QUIRK_NONE },
431 { 0x1371, 0x0013, RadioRFMD2958, ATU_QUIRK_NONE },
432 { 0x1371, 0x0002, RadioRFMD, ATU_QUIRK_NONE },
433 { 0x1371, 0x0014, RadioRFMD2958, ATU_QUIRK_NONE },
434 { 0x1371, 0x5743, RadioRFMD, ATU_QUIRK_NONE },
435 { 0x2001, 0x3200, RadioRFMD, ATU_QUIRK_NONE },
436 { 0x1044, 0x8003, RadioRFMD, ATU_QUIRK_NONE },
437 { 0x1690, 0x0701, RadioRFMD2958_SMC,
438 ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
439 { 0x03f0, 0x011c, RadioIntersil, ATU_QUIRK_NONE },
440 { 0x8086, 0x0200, RadioIntersil, ATU_QUIRK_NONE },
441 { 0x04bb, 0x0919, RadioIntersil, ATU_QUIRK_NONE },
442 { 0x05dc, 0xa002, RadioRFMD, ATU_QUIRK_NONE },
443 { 0x066b, 0x2211, RadioIntersil, ATU_QUIRK_NONE },
444 { 0x077b, 0x2219, RadioRFMD, ATU_QUIRK_NONE },
445 { 0x077b, 0x2219, RadioRFMD, ATU_QUIRK_NONE },
446 { 0x1915, 0x2233, RadioRFMD2958, ATU_QUIRK_NONE },
447 { 0x0db0, 0x1020, RadioRFMD2958, ATU_QUIRK_NONE },
448 { 0x0864, 0x4100, RadioIntersil, ATU_QUIRK_NONE },
449 { 0x0864, 0x4102, RadioRFMD, ATU_QUIRK_NONE },
450 { 0x1557, 0x0002, RadioRFMD2958_SMC,
451 ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
452 { 0x2019, 0x3220, RadioRFMD, ATU_QUIRK_NONE },
453 { 0x055d, 0xa000, AT76C503_i3863, ATU_QUIRK_NONE },
454 { 0x0681, 0x001b, RadioRFMD, ATU_QUIRK_NONE },
455 { 0x0d5c, 0xa001, RadioIntersil, ATU_QUIRK_NONE },
456 { 0x0d5c, 0xa002, AT76C503_RFMD_ACC, ATU_QUIRK_NONE },
457 { 0x0b3b, 0x1612, RadioIntersil, ATU_QUIRK_NONE },
458 { 0x0cde, 0x0001, RadioIntersil, ATU_QUIRK_NONE },
459};
460
461static struct atu_firmware atu_fw_table[] = {
462 {
463 RadioRFMD,
464 atmel_fw_rfmd_int,
465 atmel_fw_rfmd_ext,
466 sizeof (atmel_fw_rfmd_int),
467 sizeof (atmel_fw_rfmd_ext),
468 0
469 },
470 {
471 RadioRFMD2958,
472 atmel_fw_rfmd2958_int,
473 atmel_fw_rfmd2958_ext,
474 sizeof (atmel_fw_rfmd2958_int),
475 sizeof (atmel_fw_rfmd2958_ext),
476 81
477 },
478 {
479 RadioRFMD2958_SMC,
480 atmel_fw_rfmd2958_smc_int,
481 atmel_fw_rfmd2958_smc_ext,
482 sizeof (atmel_fw_rfmd2958_smc_int),
483 sizeof (atmel_fw_rfmd2958_smc_ext),
484 0
485 },
486 {
487 RadioIntersil,
488 atmel_fw_intersil_int,
489 atmel_fw_intersil_ext,
490 sizeof (atmel_fw_intersil_int),
491 sizeof (atmel_fw_intersil_ext),
492 0
493 },
494 {
495 AT76C503_i3863,
496 atmel_at76c503_i3863_fw_int,
497 atmel_at76c503_i3863_fw_ext,
498 sizeof (atmel_at76c503_i3863_fw_int),
499 sizeof (atmel_at76c503_i3863_fw_ext),
500 0
501 },
502 {
503 AT76C503_RFMD_ACC,
504 atmel_at76c503_rfmd_acc_fw_int,
505 atmel_at76c503_rfmd_acc_fw_ext,
506 sizeof (atmel_at76c503_rfmd_acc_fw_int),
507 sizeof (atmel_at76c503_rfmd_acc_fw_ext),
508 0
509 },
510 {
511 AT76C505_RFMD,
512 atmel_at76c505_rfmd_fw_int,
513 atmel_at76c505_rfmd_fw_ext,
514 sizeof (atmel_at76c505_rfmd_fw_int),
515 sizeof (atmel_at76c505_rfmd_fw_ext),
516 0
517 }
518};
519
520#ifdef __cplusplus
521}
522#endif
523
524#endif /* _ATU_H */