2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
8 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice unmodified, this list of conditions, and the following
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #ifndef _SYS_IPW2100_IMPL_H
34 #define _SYS_IPW2100_IMPL_H
41 * Intel Wireless PRO/2100 mini-PCI adapter driver
42 * ipw2100_impl.h includes:
43 * . implementation of ipw2100
44 * . hardware operation and interface define for ipw2100
45 * . firmware operation and interface define for ipw2100
48 #include <sys/sunddi.h>
50 #include <sys/net80211.h>
53 * Implementation of ipw2100
55 #define IPW2100_NODENAME "ipw"
57 #define IPW2100_PCI_CFG_RNUM (0) /* pci config space */
58 #define IPW2100_PCI_CSR_RNUM (1) /* device CSR space */
60 #define IPW2100_NUM_TXBD (128)
61 #define IPW2100_TXBD_SIZE (IPW2100_NUM_TXBD * sizeof (struct ipw2100_bd))
62 #define IPW2100_NUM_TXBUF (IPW2100_NUM_TXBD/2) /* ipw2100_txb number */
63 #define IPW2100_TXBUF_SIZE (sizeof (struct ipw2100_txb))
65 #define IPW2100_NUM_RXBD (128)
66 #define IPW2100_STATUS_SIZE (IPW2100_NUM_RXBD * sizeof (struct ipw2100_status))
67 #define IPW2100_RXBD_SIZE (IPW2100_NUM_RXBD * sizeof (struct ipw2100_bd))
68 #define IPW2100_NUM_RXBUF (IPW2100_NUM_RXBD)
69 #define IPW2100_RXBUF_SIZE (sizeof (struct ipw2100_rxb))
71 #define IPW2100_CMD_SIZE (sizeof (struct ipw2100_cmd))
74 ddi_dma_handle_t dr_hnd
;
75 ddi_acc_handle_t dr_acc
;
76 ddi_dma_cookie_t dr_cookie
;
84 struct ipw2100_firmware
{
85 uint8_t *bin_base
; /* image */
87 uint8_t *fw_base
; /* firmware code */
89 uint8_t *uc_base
; /* u-controller code */
94 * per-instance soft-state structure
96 struct ipw2100_softc
{
97 struct ieee80211com sc_ic
;
99 int (*sc_newstate
)(struct ieee80211com
*,
100 enum ieee80211_state
, int);
104 ddi_acc_handle_t sc_ioh
;
107 ddi_iblock_cookie_t sc_iblk
;
109 ddi_softintr_t sc_link_softint
;
111 int32_t sc_linkstate
;
112 /* mutex to protect interrupt handler */
114 kcondvar_t sc_fw_cond
;
117 #define IPW2100_FLAG_FW_CACHED (1 << 0)
118 #define IPW2100_FLAG_FW_INITED (1 << 1)
119 #define IPW2100_FLAG_RUNNING (1 << 2)
120 #define IPW2100_FLAG_LINK_CHANGE (1 << 3)
121 #define IPW2100_FLAG_TX_SCHED (1 << 4)
122 #define IPW2100_FLAG_CMD_WAIT (1 << 5)
123 #define IPW2100_FLAG_SCAN_COMPLETE (1 << 6)
124 #define IPW2100_FLAG_HW_ERR_RECOVER (1 << 7)
125 #define IPW2100_FLAG_QUIESCED (1 << 8)
126 #define IPW2100_FLAG_HAS_RADIO_SWITCH (1 << 16)
128 struct ipw2100_cmd
*sc_cmd
;
129 int sc_done
; /* command is done */
130 kcondvar_t sc_cmd_cond
;
131 /* reschedule lock */
132 kmutex_t sc_resched_lock
;
133 /* tx ring, bd->hdr&buf */
135 kcondvar_t sc_tx_cond
;
138 struct ipw2100_bd
*sc_txbd
;
139 struct ipw2100_txb
*sc_txbufs
[IPW2100_NUM_TXBUF
];
140 /* rx ring, status, bd->buf */
143 struct ipw2100_status
*sc_status
;
144 struct ipw2100_bd
*sc_rxbd
;
145 struct ipw2100_rxb
*sc_rxbufs
[IPW2100_NUM_RXBUF
];
147 struct dma_region sc_dma_txbd
; /* tx buffer descriptor */
148 struct dma_region sc_dma_txbufs
[IPW2100_NUM_TXBUF
];
149 struct dma_region sc_dma_rxbd
; /* rx buffer descriptor */
150 struct dma_region sc_dma_rxbufs
[IPW2100_NUM_RXBUF
];
151 struct dma_region sc_dma_status
;
152 struct dma_region sc_dma_cmd
; /* command */
153 /* hw configuration values */
154 uint8_t sc_macaddr
[IEEE80211_ADDR_LEN
];
156 /* MAC address string */
159 uint32_t sc_table1_base
;
160 uint32_t sc_table2_base
;
162 struct ipw2100_firmware sc_fw
;
163 /* mfthread related */
165 kcondvar_t sc_mfthread_cv
;
166 kcondvar_t sc_scan_cv
; /* used for active scan */
167 kthread_t
*sc_mf_thread
;
168 uint32_t sc_mfthread_switch
; /* 0/1 indicate off/on */
173 * RING_BACKWARD - move 'x' backward 's' steps in a 'b'-sized ring
174 * RING_FORWARD - move 'x' forward 's' steps in a 'b'-sized ring
176 * note that there must be 0 <= 'x' < 'b' && 0 <= 's' < 'b'
178 #define RING_FLEN(x, y, b) ((((x) > (y)) ? ((b)+(y)-(x)) : ((y)-(x))))
179 #define RING_FORWARD(x, s, b) (((x)+(s))%(b))
180 #define RING_BACKWARD(x, s, b) RING_FORWARD((x), (b)-(s), (b))
185 #define OFFSETOF(s, m) ((size_t)(&(((s *)0)->m)))
187 extern int ipw2100_init(struct ipw2100_softc
*sc
);
188 extern int ipw2100_disable(struct ipw2100_softc
*sc
);
191 * Below structure and functions will be used for statistic
203 extern void ipw2100_get_statistics(struct ipw2100_softc
*sc
);
206 * Hardware related definations and interfaces.
208 #define IPW2100_CSR_INTR (0x0008)
209 #define IPW2100_CSR_INTR_MASK (0x000c)
210 #define IPW2100_CSR_INDIRECT_ADDR (0x0010)
211 #define IPW2100_CSR_INDIRECT_DATA (0x0014)
212 #define IPW2100_CSR_AUTOINC_ADDR (0x0018)
213 #define IPW2100_CSR_AUTOINC_DATA (0x001c)
214 #define IPW2100_CSR_RST (0x0020)
215 #define IPW2100_CSR_CTL (0x0024)
216 #define IPW2100_CSR_IO (0x0030)
217 #define IPW2100_CSR_DEBUG_AREA (0x0090)
219 #define IPW2100_CSR_TX_BD_BASE (0x0200)
220 #define IPW2100_CSR_TX_BD_SIZE (0x0204)
221 #define IPW2100_CSR_RX_BD_BASE (0x0240)
222 #define IPW2100_CSR_RX_STATUS_BASE (0x0244)
223 #define IPW2100_CSR_RX_BD_SIZE (0x0248)
224 #define IPW2100_CSR_TABLE1_BASE (0x0380)
225 #define IPW2100_CSR_TABLE2_BASE (0x0384)
227 * tx-rd-index the entry to be processed by HW, i.e. empty tx buffer
228 * tx-wr-index the entry just being filled by SW with new data to transmit
230 #define IPW2100_CSR_TX_READ_INDEX (0x0280)
231 #define IPW2100_CSR_TX_WRITE_INDEX (0x0f80)
233 * rx-rd-index the entry just being processed by HW, i.e. new received data
234 * rx-wr-index the entry just being set by SW to empty buffer to receive
236 #define IPW2100_CSR_RX_READ_INDEX (0x02a0)
237 #define IPW2100_CSR_RX_WRITE_INDEX (0x0fa0)
240 * CSR flags: IPW2100_CSR_INTR
241 * The interrupt register is used to indicate the h/w status
243 #define IPW2100_INTR_TX_TRANSFER (0x00000001)
244 #define IPW2100_INTR_RX_TRANSFER (0x00000002)
245 #define IPW2100_INTR_STATUS_CHANGE (0x00000010)
246 #define IPW2100_INTR_COMMAND_DONE (0x00010000)
247 #define IPW2100_INTR_FW_INIT_DONE (0x01000000)
248 #define IPW2100_INTR_FATAL_ERROR (0x40000000)
249 #define IPW2100_INTR_PARITY_ERROR (0x80000000)
250 #define IPW2100_INTR_MASK_ALL (IPW2100_INTR_TX_TRANSFER | \
251 IPW2100_INTR_RX_TRANSFER | \
252 IPW2100_INTR_STATUS_CHANGE | \
253 IPW2100_INTR_COMMAND_DONE | \
254 IPW2100_INTR_FW_INIT_DONE | \
255 IPW2100_INTR_FATAL_ERROR | \
256 IPW2100_INTR_PARITY_ERROR)
257 #define IPW2100_INTR_MASK_ERR (IPW2100_INTR_FATAL_ERROR | \
258 IPW2100_INTR_PARITY_ERROR)
261 * CSR flags: IPW2100_CSR_RST
262 * The reset register is used to reset hardware
264 #define IPW2100_RST_PRINCETON_RESET (0x00000001)
265 #define IPW2100_RST_SW_RESET (0x00000080)
266 #define IPW2100_RST_MASTER_DISABLED (0x00000100)
267 #define IPW2100_RST_STOP_MASTER (0x00000200)
270 * CSR flags: IPW2100_CSR_CTL
272 #define IPW2100_CTL_CLOCK_READY (0x00000001)
273 #define IPW2100_CTL_ALLOW_STANDBY (0x00000002)
274 #define IPW2100_CTL_INIT (0x00000004)
277 * CSR flags: IPW2100_CSR_IO
279 #define IPW2100_IO_GPIO1_ENABLE (0x00000008)
280 #define IPW2100_IO_GPIO1_MASK (0x0000000c)
281 #define IPW2100_IO_GPIO3_MASK (0x000000c0)
282 #define IPW2100_IO_LED_OFF (0x00002000)
283 #define IPW2100_IO_RADIO_DISABLED (0x00010000)
288 #define IPW2100_STATE_ASSOCIATED (0x0004)
289 #define IPW2100_STATE_ASSOCIATION_LOST (0x0008)
290 #define IPW2100_STATE_SCAN_COMPLETE (0x0020)
291 #define IPW2100_STATE_RADIO_DISABLED (0x0100)
292 #define IPW2100_STATE_DISABLED (0x0200)
293 #define IPW2100_STATE_SCANNING (0x0800)
298 #define IPW2100_INFO_LOCK (480)
299 #define IPW2100_INFO_APS_CNT (604)
300 #define IPW2100_INFO_APS_BASE (608)
301 #define IPW2100_INFO_CARD_DISABLED (628)
302 #define IPW2100_INFO_CURRENT_CHANNEL (756)
303 #define IPW2100_INFO_CURRENT_TX_RATE (768)
308 #define IPW2100_INFO_CURRENT_SSID (48)
309 #define IPW2100_INFO_CURRENT_BSSID (112)
314 #define IPW2100_RATE_DS1 (1)
315 #define IPW2100_RATE_DS2 (2)
316 #define IPW2100_RATE_DS5 (4)
317 #define IPW2100_RATE_DS11 (8)
319 /* hw structures, packed */
322 * firmware binary image header
324 struct ipw2100_firmware_hdr
{
338 #define IPW2100_BD_FLAG_TX_LAST_FRAGMENT (0x08)
339 #define IPW2100_BD_FLAG_TX_NOT_LAST_FRAGMENT (0x01)
341 #define IPW2100_BD_FLAG_TX_FRAME_802_3 (0x00)
342 #define IPW2100_BD_FLAG_TX_FRAME_COMMAND (0x02)
343 #define IPW2100_BD_FLAG_TX_FRAME_802_11 (0x04)
344 /* number of fragments, only 1st BD is needed */
352 struct ipw2100_status
{
355 #define IPW2100_STATUS_CODE_COMMAND (0)
356 #define IPW2100_STATUS_CODE_NEWSTATE (1)
357 #define IPW2100_STATUS_CODE_DATA_802_11 (2)
358 #define IPW2100_STATUS_CODE_DATA_802_3 (3)
359 #define IPW2100_STATUS_CODE_NOTIFICATION (4)
361 #define IPW2100_STATUS_FLAG_DECRYPTED (0x01)
362 #define IPW2100_STATUS_FLAG_WEP_ENCRYPTED (0x02)
363 #define IPW2100_STATUS_FLAG_CRC_ERROR (0x04)
364 /* received signal strength indicator */
378 uint8_t key
[IEEE80211_KEYBUF_SIZE
];
379 uint8_t reserved
[10];
380 uint8_t saddr
[IEEE80211_ADDR_LEN
];
381 uint8_t daddr
[IEEE80211_ADDR_LEN
];
390 #define IPW2100_CMD_ENABLE (2)
391 #define IPW2100_CMD_SET_CONFIGURATION (6)
392 #define IPW2100_CMD_SET_ESSID (8)
393 #define IPW2100_CMD_SET_MANDATORY_BSSID (9)
394 #define IPW2100_CMD_SET_AUTH_TYPE (10)
395 #define IPW2100_CMD_SET_MAC_ADDRESS (11)
396 #define IPW2100_CMD_SET_MODE (12)
397 #define IPW2100_CMD_SET_I18N_MODE (13)
398 #define IPW2100_CMD_SET_CHANNEL (14)
399 #define IPW2100_CMD_SET_RTS_THRESHOLD (15)
400 #define IPW2100_CMD_SET_FRAG_THRESHOLD (16)
401 #define IPW2100_CMD_SET_POWER_MODE (17)
402 #define IPW2100_CMD_SET_TX_RATES (18)
403 #define IPW2100_CMD_SET_BASIC_TX_RATES (19)
404 #define IPW2100_CMD_SET_WEP_KEY (20)
405 #define IPW2100_CMD_SET_WEP_KEY_INDEX (25)
406 #define IPW2100_CMD_SET_WEP_FLAGS (26)
407 #define IPW2100_CMD_ADD_MULTICAST (27)
408 #define IPW2100_CMD_CLR_MULTICAST (28)
409 #define IPW2100_CMD_SET_BEACON_INTERVAL (29)
410 #define IPW2100_CMD_CLR_STATISTICS (31)
411 #define IPW2100_CMD_SEND (33)
412 #define IPW2100_CMD_SET_TX_POWER_INDEX (36)
413 #define IPW2100_CMD_BROADCAST_SCAN (43)
414 #define IPW2100_CMD_DISABLE (44)
415 #define IPW2100_CMD_SET_DESIRED_BSSID (45)
416 #define IPW2100_CMD_SET_SCAN_OPTIONS (46)
417 #define IPW2100_CMD_PREPARE_POWER_DOWN (58)
418 #define IPW2100_CMD_DISABLE_PHY (61)
419 #define IPW2100_CMD_SET_SECURITY_INFORMATION (67)
420 #define IPW2100_CMD_SET_WPA_IE (69)
426 uint8_t reserved
[68];
430 * IPW2100_CMD_SET_POWER_MODE
432 #define IPW2100_POWER_MODE_CAM (0)
433 #define IPW2100_POWER_AUTOMATIC (6)
436 * IPW2100_CMD_SET_MODE
438 #define IPW2100_MODE_BSS (0)
439 #define IPW2100_MODE_IBSS (1)
440 #define IPW2100_MODE_MONITOR (2)
443 * structure for IPW2100_CMD_SET_WEP_KEY
445 struct ipw2100_wep_key
{
452 * structure for IPW2100_CMD_SET_SECURITY_INFORMATION
454 struct ipw2100_security
{
456 #define IPW2100_CIPHER_NONE (0x00000001)
457 #define IPW2100_CIPHER_WEP40 (0x00000002)
458 #define IPW2100_CIPHER_WEP104 (0x00000020)
461 #define IPW2100_AUTH_OPEN (0)
462 #define IPW2100_AUTH_SHARED (1)
463 uint8_t replay_counters_number
;
464 uint8_t unicast_using_group
;
468 * structure for IPW2100_CMD_SET_SCAN_OPTIONS
470 struct ipw2100_scan_options
{
472 #define IPW2100_SCAN_DO_NOT_ASSOCIATE (0x00000001)
473 #define IPW2100_SCAN_PASSIVE (0x00000008)
478 * structure for IPW2100_CMD_SET_CONFIGURATION
480 struct ipw2100_configuration
{
482 #define IPW2100_CFG_PROMISCUOUS (0x00000004)
483 #define IPW2100_CFG_PREAMBLE_AUTO (0x00000010)
484 #define IPW2100_CFG_IBSS_AUTO_START (0x00000020)
485 #define IPW2100_CFG_802_1x_ENABLE (0x00004000)
486 #define IPW2100_CFG_BSS_MASK (0x00008000)
487 #define IPW2100_CFG_IBSS_MASK (0x00010000)
493 * element in AP table
495 struct ipw2100_node
{
496 uint32_t reserved_1
[2];
497 uint8_t bssid
[IEEE80211_ADDR_LEN
];
504 uint8_t reserved_4
[28];
505 uint8_t essid
[IEEE80211_NWID_LEN
];
508 uint8_t reserved_6
[7];
514 * transmit buffer block
517 struct ipw2100_hdr txb_hdr
; /* header */
518 uint8_t txb_dat
[IEEE80211_MAX_LEN
]; /* payload */
522 * maximum frame header lenght: 4 MAC addresses + 1 fc + 1 id + 1 seqctl
524 #define IEEE80211_MAX_FHLEN (4*6+2+2+2)
527 * receive buffer block
530 uint8_t rxb_dat
[IEEE80211_MAX_FHLEN
/* frame */
531 + IEEE80211_MAX_LEN
/* payload */
532 + IEEE80211_CRC_LEN
]; /* FCS */
538 #define IPW2100_ROM_RADIO (0x11)
539 #define IPW2100_ROM_MAC (0x21)
540 #define IPW2100_ROM_CHANNEL_LIST (0x37)
545 #define IPW2100_IMEM_EEPROM_CTL (0x00300040)
546 #define IPW2100_EEPROM_DELAY (1)
549 * CSR access routines
551 extern uint8_t ipw2100_csr_get8(struct ipw2100_softc
*sc
, uint32_t off
);
552 extern uint16_t ipw2100_csr_get16(struct ipw2100_softc
*sc
, uint32_t off
);
553 extern uint32_t ipw2100_csr_get32(struct ipw2100_softc
*sc
, uint32_t off
);
554 extern void ipw2100_csr_rep_get16(struct ipw2100_softc
*sc
, uint32_t off
,
555 uint16_t *buf
, size_t cnt
);
556 extern void ipw2100_csr_put8(struct ipw2100_softc
*sc
, uint32_t off
,
558 extern void ipw2100_csr_put16(struct ipw2100_softc
*sc
,
559 uint32_t off
, uint16_t val
);
560 extern void ipw2100_csr_put32(struct ipw2100_softc
*sc
,
561 uint32_t off
, uint32_t val
);
562 extern void ipw2100_csr_rep_put8(struct ipw2100_softc
*sc
,
563 uint32_t off
, uint8_t *buf
, size_t cnt
);
564 extern uint8_t ipw2100_imem_get8(struct ipw2100_softc
*sc
, int32_t addr
);
565 extern uint16_t ipw2100_imem_get16(struct ipw2100_softc
*sc
,
567 extern uint32_t ipw2100_imem_get32(struct ipw2100_softc
*sc
,
569 extern void ipw2100_imem_rep_get16(struct ipw2100_softc
*sc
,
570 uint32_t addr
, uint16_t *buf
, size_t cnt
);
571 extern void ipw2100_imem_put8(struct ipw2100_softc
*sc
,
572 uint32_t addr
, uint8_t val
);
573 extern void ipw2100_imem_put16(struct ipw2100_softc
*sc
,
574 uint32_t addr
, uint16_t val
);
575 extern void ipw2100_imem_put32(struct ipw2100_softc
*sc
,
576 uint32_t addr
, uint32_t val
);
577 extern void ipw2100_imem_rep_put8(struct ipw2100_softc
*sc
,
578 uint32_t addr
, uint8_t *buf
, size_t cnt
);
579 extern void ipw2100_imem_getbuf(struct ipw2100_softc
*sc
,
580 uint32_t addr
, uint8_t *buf
, size_t cnt
);
581 extern void ipw2100_imem_putbuf(struct ipw2100_softc
*sc
,
582 uint32_t addr
, uint8_t *buf
, size_t cnt
);
583 extern void ipw2100_rom_control(struct ipw2100_softc
*sc
, uint32_t val
);
584 extern uint8_t ipw2100_table1_get8(struct ipw2100_softc
*sc
, uint32_t off
);
585 extern uint32_t ipw2100_table1_get32(struct ipw2100_softc
*sc
,
587 extern void ipw2100_table1_put32(struct ipw2100_softc
*sc
,
588 uint32_t off
, uint32_t val
);
589 extern int ipw2100_table2_getbuf(struct ipw2100_softc
*sc
,
590 uint32_t off
, uint8_t *buf
, uint32_t *len
);
592 extern uint16_t ipw2100_rom_get16(struct ipw2100_softc
*sc
, uint8_t addr
);
595 * Firmware related definations and interfaces.
597 extern int ipw2100_cache_firmware(struct ipw2100_softc
*sc
);
598 extern int ipw2100_free_firmware(struct ipw2100_softc
*sc
);
599 extern int ipw2100_load_uc(struct ipw2100_softc
*sc
);
600 extern int ipw2100_load_fw(struct ipw2100_softc
*sc
);
606 #endif /* _SYS_IPW2100_IMPL_H */