xref: /onnv-gate/usr/src/uts/common/io/iwi/ipw2200_impl.h (revision 7809:67aa5a1da382)
13847Seh146360 /*
27194Seh146360  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
33847Seh146360  * Use is subject to license terms.
43847Seh146360  */
53847Seh146360 
63847Seh146360 /*
73847Seh146360  * Copyright (c) 2004, 2005
83847Seh146360  *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
93847Seh146360  *
103847Seh146360  * Redistribution and use in source and binary forms, with or without
113847Seh146360  * modification, are permitted provided that the following conditions
123847Seh146360  * are met:
133847Seh146360  * 1. Redistributions of source code must retain the above copyright
143847Seh146360  *    notice unmodified, this list of conditions, and the following
153847Seh146360  *    disclaimer.
163847Seh146360  * 2. Redistributions in binary form must reproduce the above copyright
173847Seh146360  *    notice, this list of conditions and the following disclaimer in the
183847Seh146360  *    documentation and/or other materials provided with the distribution.
193847Seh146360  *
203847Seh146360  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
213847Seh146360  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
223847Seh146360  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
233847Seh146360  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
243847Seh146360  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
253847Seh146360  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
263847Seh146360  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
273847Seh146360  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
283847Seh146360  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
293847Seh146360  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
303847Seh146360  * SUCH DAMAGE.
313847Seh146360  */
323847Seh146360 
333847Seh146360 #ifndef _SYS_IPW2200_IMPL_H
343847Seh146360 #define	_SYS_IPW2200_IMPL_H
353847Seh146360 
363847Seh146360 #ifdef __cplusplus
373847Seh146360 extern "C" {
383847Seh146360 #endif
393847Seh146360 
403847Seh146360 /*
413847Seh146360  * Intel Wireless PRO/2200 mini-pci adapter driver
423847Seh146360  * ipw2200_impl.h includes:
433847Seh146360  * 	. implementation of ipw2200
443847Seh146360  * 	. hardware operations and interface definations for ipw2200
453847Seh146360  * 	. firmware operations and interface definations for ipw2200
463847Seh146360  */
473847Seh146360 #include <sys/ddi.h>
483847Seh146360 #include <sys/sunddi.h>
493847Seh146360 #include <sys/mac.h>
503847Seh146360 #include <sys/mac_wifi.h>
513847Seh146360 #include <sys/net80211.h>
523847Seh146360 
533847Seh146360 /*
543847Seh146360  * Implementation of ipw2200
553847Seh146360  */
563847Seh146360 #define	IPW2200_PCI_CFG_RNUM 	(0) /* pci config space */
573847Seh146360 #define	IPW2200_PCI_CSR_RNUM 	(1) /* device CSR space */
583847Seh146360 #define	IPW2200_PCI_INTR_NUM	(0) /* interrupt number */
593847Seh146360 
603847Seh146360 #define	IPW2200_TX_RING_SIZE 	(64)
613847Seh146360 #define	IPW2200_CMD_RING_SIZE	(16)
623847Seh146360 #define	IPW2200_RX_RING_SIZE 	(32)
633847Seh146360 
643847Seh146360 struct dma_region {
653847Seh146360 	ddi_dma_handle_t	dr_hnd;
663847Seh146360 	ddi_acc_handle_t	dr_acc;
673847Seh146360 	ddi_dma_cookie_t	dr_cookie;
683847Seh146360 	uint_t			dr_ccnt;
693847Seh146360 	uint32_t		dr_pbase;
703847Seh146360 	caddr_t			dr_base;
713847Seh146360 	size_t			dr_size;
723847Seh146360 	const char		*dr_name;
733847Seh146360 };
743847Seh146360 
753847Seh146360 struct ipw2200_firmware {
763847Seh146360 	uint8_t			*boot_base; /* boot code */
773847Seh146360 	size_t			boot_size;
783847Seh146360 	uint8_t			*uc_base; /* u-controller code */
793847Seh146360 	size_t			uc_size;
803847Seh146360 	uint8_t			*fw_base; /* firmware code */
813847Seh146360 	size_t			fw_size;
823847Seh146360 };
833847Seh146360 
843847Seh146360 /*
857194Seh146360  * besides the statistic counted by net80211, driver can also record
867194Seh146360  * statistic data while process
877194Seh146360  */
887194Seh146360 struct ipw2200_stats {
897194Seh146360 	uint32_t		sc_rx_len_err;
907194Seh146360 	uint32_t		sc_tx_discard;
917194Seh146360 	uint32_t		sc_tx_alloc_fail;
927194Seh146360 	uint32_t		sc_tx_encap_fail;
937194Seh146360 	uint32_t		sc_tx_crypto_fail;
947194Seh146360 };
957194Seh146360 
967194Seh146360 /*
973847Seh146360  * per-instance soft-state structure
983847Seh146360  */
993847Seh146360 struct ipw2200_softc {
1003847Seh146360 	struct ieee80211com	sc_ic;
1013847Seh146360 	dev_info_t		*sc_dip;
1023847Seh146360 	int	(*sc_newstate)(struct ieee80211com *,
1033847Seh146360 	    enum ieee80211_state, int);
1043847Seh146360 	void    (*sc_node_free)(struct ieee80211com *);
1053847Seh146360 	int			sc_authmode;
1063847Seh146360 
1073847Seh146360 	/* CSR */
1083847Seh146360 	ddi_acc_handle_t	sc_ioh;
1093847Seh146360 	caddr_t			sc_regs;
1103847Seh146360 	/* mutex to protect interrupt handler */
1113847Seh146360 	kmutex_t		sc_ilock;
1123847Seh146360 	/* interrupt iblock cookie */
1133847Seh146360 	ddi_iblock_cookie_t 	sc_iblk;
1143847Seh146360 	/* soft interrupt */
1153847Seh146360 	ddi_softintr_t		sc_link_softint;
1163847Seh146360 	/* link status */
1173847Seh146360 	int32_t			sc_linkstate;
1183847Seh146360 	/* flags */
1193847Seh146360 	uint32_t		sc_flags;
1203847Seh146360 #define	IPW2200_FLAG_FW_CACHED		(1 << 0)
1213847Seh146360 #define	IPW2200_FLAG_FW_INITED		(1 << 1)
1223847Seh146360 #define	IPW2200_FLAG_RUNNING		(1 << 2)
1233847Seh146360 #define	IPW2200_FLAG_LINK_CHANGE	(1 << 3)
1243847Seh146360 #define	IPW2200_FLAG_TX_SCHED		(1 << 4)
1253847Seh146360 #define	IPW2200_FLAG_SCANNING		(1 << 5)
1263847Seh146360 #define	IPW2200_FLAG_HW_ERR_RECOVER	(1 << 6)
1275485Seh146360 #define	IPW2200_FLAG_ASSOCIATED		(1 << 7)
1287194Seh146360 #define	IPW2200_FLAG_SUSPEND		(1 << 8)
129*7809SFei.Feng@Sun.COM #define	IPW2200_FLAG_QUIESCED		(1 << 9)
1303847Seh146360 #define	IPW2200_FLAG_HAS_RADIO_SWITCH	(1 << 16)
1313847Seh146360 	/* firmware download */
1323847Seh146360 	int			sc_fw_ok;
1333847Seh146360 	kcondvar_t		sc_fw_cond;
1343847Seh146360 
1353847Seh146360 	/* command desc ring */
1363847Seh146360 	kmutex_t		sc_cmd_lock;
1373847Seh146360 	kcondvar_t		sc_cmd_cond;
1383847Seh146360 	uint32_t		sc_cmd_cur;
1393847Seh146360 	uint32_t		sc_cmd_free;
1403847Seh146360 	struct ipw2200_cmd_desc	*sc_cmdsc;
1413847Seh146360 
1423847Seh146360 	/* command status */
1433847Seh146360 	int			sc_done[IPW2200_CMD_RING_SIZE];
1443847Seh146360 	kcondvar_t		sc_cmd_status_cond;
1453847Seh146360 
1463847Seh146360 	/* tx ring, bd->hdr&buf */
1473847Seh146360 	kmutex_t		sc_tx_lock;
1483847Seh146360 	uint32_t		sc_tx_cur;
1493847Seh146360 	uint32_t		sc_tx_free;
1503847Seh146360 	struct ipw2200_tx_desc	*sc_txdsc;
1513847Seh146360 	uint8_t			*sc_txbufs[IPW2200_TX_RING_SIZE];
1523847Seh146360 
1533847Seh146360 	/* rx ring */
1543847Seh146360 	uint32_t		sc_rx_cur;
1553847Seh146360 	uint32_t		sc_rx_free;
1563847Seh146360 	uint8_t			*sc_rxbufs[IPW2200_RX_RING_SIZE];
1573847Seh146360 
1583847Seh146360 	/* tx-desc & tx-buffer array */
1593847Seh146360 	struct dma_region	sc_dma_txdsc;
1603847Seh146360 	struct dma_region	sc_dma_txbufs[IPW2200_TX_RING_SIZE];
1613847Seh146360 	struct dma_region	sc_dma_cmdsc;
1623847Seh146360 	/* rx-buffer array */
1633847Seh146360 	struct dma_region	sc_dma_rxbufs[IPW2200_RX_RING_SIZE];
1643847Seh146360 
1653847Seh146360 	/* hw configuration values */
1663847Seh146360 	uint8_t			sc_macaddr[IEEE80211_ADDR_LEN];
1673847Seh146360 	/* MAC address string */
1683847Seh146360 	char			sc_macstr[32];
1693847Seh146360 
1703847Seh146360 	/* firmware */
1713847Seh146360 	struct ipw2200_firmware	sc_fw;
1723847Seh146360 
1735485Seh146360 	/* reschedule lock */
1745485Seh146360 	kmutex_t		sc_resched_lock;
1755485Seh146360 
1767194Seh146360 	/* pci information */
1777194Seh146360 	uint16_t		sc_vendor, sc_device, sc_subven, sc_subdev;
1787194Seh146360 
1797194Seh146360 	/* statistic counting by driver */
1807194Seh146360 	struct ipw2200_stats	sc_stats;
1817194Seh146360 
1823847Seh146360 	/* mfthread related, mfthread is used to handle asynchronous task */
1833847Seh146360 	kthread_t		*sc_mf_thread;
1843847Seh146360 	kmutex_t		sc_mflock;
1853847Seh146360 	int			sc_mfthread_switch;
1863847Seh146360 	kcondvar_t		sc_mfthread_req;
1873847Seh146360 	kcondvar_t		sc_mfthread_cv;
1883847Seh146360 
1893847Seh146360 };
1903847Seh146360 
1913847Seh146360 /*
1923847Seh146360  * RING_BACKWARD - move 'x' backward 's' steps in a 'b'- sized ring
1933847Seh146360  * RING_FORWARD	 - move 'x' forward 's' steps in a 'b'- sized ring
1943847Seh146360  *
1953847Seh146360  * note that there must be 0 <= 'x' < 'b' && 0 <= 's' < 'b'
1963847Seh146360  */
1973847Seh146360 #define	RING_FLEN(x, y, b)	((((x) > (y)) ? ((b)+(y)-(x)) : ((y)-(x))))
1983847Seh146360 #define	RING_FORWARD(x, s, b)	(((x)+(s))%(b))
1993847Seh146360 #define	RING_BACKWARD(x, s, b)	RING_FORWARD((x), (b)-(s), (b))
2003847Seh146360 
2013847Seh146360 extern int ipw2200_init(struct ipw2200_softc *sc);
2023847Seh146360 extern void ipw2200_wifi_ioctl(struct ipw2200_softc *, queue_t *,
2033847Seh146360     mblk_t *, uint32_t);
2043847Seh146360 extern int ipw2200_dma_region_alloc(struct ipw2200_softc *sc,
2053847Seh146360     struct dma_region *dr, size_t size, uint_t dir, uint_t flags);
2063847Seh146360 extern void ipw2200_dma_region_free(struct dma_region *dr);
2073847Seh146360 extern int ipw2200_disable(struct ipw2200_softc *sc);
2083847Seh146360 extern int ipw2200_start_scan(struct ipw2200_softc *sc);
2093847Seh146360 
2103847Seh146360 /*
2113847Seh146360  * get radio off/on status
2123847Seh146360  */
2133847Seh146360 extern int ipw2200_radio_status(struct ipw2200_softc *sc);
2143847Seh146360 
2153847Seh146360 /*
2163847Seh146360  * Below structure and functions will be used for statistic, which will be
2173847Seh146360  * displayed when the wificonfig running...
2183847Seh146360  */
2193847Seh146360 struct statistic {
2203847Seh146360 	int		index;
2213847Seh146360 	const char	*desc;
2223847Seh146360 };
2233847Seh146360 extern void ipw2200_get_statistics(struct ipw2200_softc *sc);
2243847Seh146360 
2253847Seh146360 /*
2263847Seh146360  * Hardware related definations and interfaces.
2273847Seh146360  */
2283847Seh146360 #define	IPW2200_CSR_INTR		(0x0008)
2293847Seh146360 #define	IPW2200_CSR_INTR_MASK		(0x000c)
2303847Seh146360 #define	IPW2200_CSR_INDIRECT_ADDR	(0x0010)
2313847Seh146360 #define	IPW2200_CSR_INDIRECT_DATA	(0x0014)
2323847Seh146360 #define	IPW2200_CSR_AUTOINC_ADDR	(0x0018)
2333847Seh146360 #define	IPW2200_CSR_AUTOINC_DATA	(0x001c)
2343847Seh146360 #define	IPW2200_CSR_RST			(0x0020)
2353847Seh146360 #define	IPW2200_CSR_CTL			(0x0024)
2363847Seh146360 #define	IPW2200_CSR_IO			(0x0030)
2373847Seh146360 #define	IPW2200_CSR_CMD_BASE		(0x0200)
2383847Seh146360 #define	IPW2200_CSR_CMD_SIZE		(0x0204)
2393847Seh146360 #define	IPW2200_CSR_TX1_BASE		(0x0208)
2403847Seh146360 #define	IPW2200_CSR_TX1_SIZE		(0x020c)
2413847Seh146360 #define	IPW2200_CSR_TX2_BASE		(0x0210)
2423847Seh146360 #define	IPW2200_CSR_TX2_SIZE		(0x0214)
2433847Seh146360 #define	IPW2200_CSR_TX3_BASE		(0x0218)
2443847Seh146360 #define	IPW2200_CSR_TX3_SIZE		(0x021c)
2453847Seh146360 #define	IPW2200_CSR_TX4_BASE		(0x0220)
2463847Seh146360 #define	IPW2200_CSR_TX4_SIZE		(0x0224)
2473847Seh146360 #define	IPW2200_CSR_CMD_READ_INDEX	(0x0280)
2483847Seh146360 #define	IPW2200_CSR_TX1_READ_INDEX	(0x0284)
2493847Seh146360 #define	IPW2200_CSR_TX2_READ_INDEX	(0x0288)
2503847Seh146360 #define	IPW2200_CSR_TX3_READ_INDEX	(0x028c)
2513847Seh146360 #define	IPW2200_CSR_TX4_READ_INDEX	(0x0290)
2523847Seh146360 #define	IPW2200_CSR_RX_READ_INDEX	(0x02a0)
2533847Seh146360 #define	IPW2200_CSR_RX_BASE		(0x0500)
2543847Seh146360 #define	IPW2200_CSR_TABLE0_SIZE		(0x0700)
2553847Seh146360 #define	IPW2200_CSR_TABLE0_BASE		(0x0704)
2563847Seh146360 #define	IPW2200_CSR_NODE_BASE		(0x0c0c)
2573847Seh146360 #define	IPW2200_CSR_CMD_WRITE_INDEX	(0x0f80)
2583847Seh146360 #define	IPW2200_CSR_TX1_WRITE_INDEX	(0x0f84)
2593847Seh146360 #define	IPW2200_CSR_TX2_WRITE_INDEX	(0x0f88)
2603847Seh146360 #define	IPW2200_CSR_TX3_WRITE_INDEX	(0x0f8c)
2613847Seh146360 #define	IPW2200_CSR_TX4_WRITE_INDEX	(0x0f90)
2623847Seh146360 #define	IPW2200_CSR_RX_WRITE_INDEX	(0x0fa0)
2633847Seh146360 #define	IPW2200_CSR_READ_INT		(0x0ff4)
2643847Seh146360 
2653847Seh146360 #define	IPW2200_CSR_CURRENTT_TX_RATE	IPW2200_CSR_TABLE0_BASE
2663847Seh146360 
2673847Seh146360 /*
2683847Seh146360  * CSR flags: IPW2200_CSR_INTR
2693847Seh146360  */
2703847Seh146360 #define	IPW2200_INTR_RX_TRANSFER	(0x00000002)
2713847Seh146360 #define	IPW2200_INTR_CMD_TRANSFER	(0x00000800)
2723847Seh146360 #define	IPW2200_INTR_TX1_TRANSFER	(0x00001000)
2733847Seh146360 #define	IPW2200_INTR_TX2_TRANSFER	(0x00002000)
2743847Seh146360 #define	IPW2200_INTR_TX3_TRANSFER	(0x00004000)
2753847Seh146360 #define	IPW2200_INTR_TX4_TRANSFER	(0x00008000)
2763847Seh146360 #define	IPW2200_INTR_FW_INITED		(0x01000000)
2773847Seh146360 #define	IPW2200_INTR_RADIO_OFF		(0x04000000)
2783847Seh146360 #define	IPW2200_INTR_FATAL_ERROR	(0x40000000)
2793847Seh146360 #define	IPW2200_INTR_PARITY_ERROR	(0x80000000)
2803847Seh146360 
2813847Seh146360 #define	IPW2200_INTR_MASK_ALL	(IPW2200_INTR_RX_TRANSFER	| \
2823847Seh146360 	IPW2200_INTR_CMD_TRANSFER	| \
2833847Seh146360 	IPW2200_INTR_TX1_TRANSFER	| \
2843847Seh146360 	IPW2200_INTR_TX2_TRANSFER	| \
2853847Seh146360 	IPW2200_INTR_TX3_TRANSFER	| \
2863847Seh146360 	IPW2200_INTR_TX4_TRANSFER	| \
2873847Seh146360 	IPW2200_INTR_FW_INITED		| \
2883847Seh146360 	IPW2200_INTR_RADIO_OFF		| \
2893847Seh146360 	IPW2200_INTR_FATAL_ERROR	| \
2903847Seh146360 	IPW2200_INTR_PARITY_ERROR)
2913847Seh146360 
2923847Seh146360 #define	IPW2200_INTR_MASK_ERR	(IPW2200_INTR_FATAL_ERROR	| \
2933847Seh146360 	IPW2200_INTR_PARITY_ERROR)
2943847Seh146360 
2953847Seh146360 /*
2963847Seh146360  * CSR flags for register: IPW2200_CSR_RST, which is used to reset h/w
2973847Seh146360  */
2983847Seh146360 #define	IPW2200_RST_PRINCETON_RESET	(0x00000001)
2993847Seh146360 #define	IPW2200_RST_STANDBY		(0x00000004)
3003847Seh146360 #define	IPW2200_RST_LED_ACTIVITY	(0x00000010)
3013847Seh146360 #define	IPW2200_RST_LED_ASSOCIATED	(0x00000020)
3023847Seh146360 #define	IPW2200_RST_LED_OFDM		(0x00000040)
3033847Seh146360 #define	IPW2200_RST_SW_RESET		(0x00000080)
3043847Seh146360 #define	IPW2200_RST_MASTER_DISABLED	(0x00000100)
3053847Seh146360 #define	IPW2200_RST_STOP_MASTER		(0x00000200)
3063847Seh146360 #define	IPW2200_RST_GATE_ODMA		(0x02000000)
3073847Seh146360 #define	IPW2200_RST_GATE_IDMA		(0x04000000)
3083847Seh146360 #define	IPW2200_RST_GATE_ADMA		(0x20000000)
3093847Seh146360 
3103847Seh146360 /*
3113847Seh146360  * CSR flags for register: IPW2200_CSR_CTL
3123847Seh146360  */
3133847Seh146360 #define	IPW2200_CTL_CLOCK_READY		(0x00000001)
3143847Seh146360 #define	IPW2200_CTL_ALLOW_STANDBY	(0x00000002)
3153847Seh146360 #define	IPW2200_CTL_INIT		(0x00000004)
3163847Seh146360 
3173847Seh146360 /*
3183847Seh146360  * CSR flags for register: IPW2200_CSR_IO
3193847Seh146360  */
3203847Seh146360 #define	IPW2200_IO_RADIO_ENABLED	(0x00010000)
3213847Seh146360 
3223847Seh146360 /*
3233847Seh146360  * CSR flags for register: IPW2200_CSR_READ_INT
3243847Seh146360  */
3253847Seh146360 #define	IPW2200_READ_INT_INIT_HOST	(0x20000000)
3263847Seh146360 
3273847Seh146360 /* table2 offsets */
3283847Seh146360 #define	IPW2200_INFO_ADAPTER_MAC	(40)
3293847Seh146360 
3303847Seh146360 /* constants for command blocks */
3313847Seh146360 #define	IPW2200_CB_DEFAULT_CTL		(0x8cea0000)
3323847Seh146360 #define	IPW2200_CB_MAXDATALEN		(8191)
3333847Seh146360 
3343847Seh146360 /* supported rates */
3353847Seh146360 #define	IPW2200_RATE_DS1		(10)
3363847Seh146360 #define	IPW2200_RATE_DS2		(20)
3373847Seh146360 #define	IPW2200_RATE_DS5		(55)
3383847Seh146360 #define	IPW2200_RATE_DS11		(110)
3393847Seh146360 #define	IPW2200_RATE_OFDM6		(13)
3403847Seh146360 #define	IPW2200_RATE_OFDM9		(15)
3413847Seh146360 #define	IPW2200_RATE_OFDM12		(5)
3423847Seh146360 #define	IPW2200_RATE_OFDM18		(7)
3433847Seh146360 #define	IPW2200_RATE_OFDM24		(9)
3443847Seh146360 #define	IPW2200_RATE_OFDM36		(11)
3453847Seh146360 #define	IPW2200_RATE_OFDM48		(1)
3463847Seh146360 #define	IPW2200_RATE_OFDM54		(3)
3473847Seh146360 
3483847Seh146360 #pragma pack(1)
3493847Seh146360 /* HW structures, packed */
3503847Seh146360 
3513847Seh146360 struct ipw2200_hdr {
3523847Seh146360 	uint8_t		type;
3533847Seh146360 #define	IPW2200_HDR_TYPE_DATA		(0)
3543847Seh146360 #define	IPW2200_HDR_TYPE_COMMAND	(1)
3553847Seh146360 #define	IPW2200_HDR_TYPE_NOTIF		(3)
3563847Seh146360 #define	IPW2200_HDR_TYPE_FRAME		(9)
3573847Seh146360 	uint8_t		seq;
3583847Seh146360 	uint8_t		flags;
3593847Seh146360 #define	IPW2200_HDR_FLAG_IRQ		(0x04)
3603847Seh146360 	uint8_t		reserved;
3613847Seh146360 };
3623847Seh146360 
3633847Seh146360 struct ipw2200_notif {
3643847Seh146360 	uint32_t	reserved[2];
3653847Seh146360 	uint8_t		type;
3663847Seh146360 #define	IPW2200_NOTIF_TYPE_SUCCESS		(0)
3673847Seh146360 #define	IPW2200_NOTIF_TYPE_UNSPECIFIED		(1)
3683847Seh146360 #define	IPW2200_NOTIF_TYPE_ASSOCIATION		(10)
3693847Seh146360 #define	IPW2200_NOTIF_TYPE_AUTHENTICATION	(11)
3703847Seh146360 #define	IPW2200_NOTIF_TYPE_SCAN_CHANNEL		(12)
3713847Seh146360 #define	IPW2200_NOTIF_TYPE_SCAN_COMPLETE	(13)
3723847Seh146360 #define	IPW2200_NOTIF_TYPE_FRAG_LENGTH		(14)
3733847Seh146360 #define	IPW2200_NOTIF_TYPE_LINK_QUALITY		(15)
3743847Seh146360 #define	IPW2200_NOTIF_TYPE_BEACON		(17)
3753847Seh146360 #define	IPW2200_NOTIF_TYPE_TGI_TX_KEY		(18)
3763847Seh146360 #define	IPW2200_NOTIF_TYPE_CALIBRATION		(20)
3773847Seh146360 #define	IPW2200_NOTIF_TYPE_NOISE		(25)
3783847Seh146360 	uint8_t		flags;
3793847Seh146360 	uint16_t	len;
3803847Seh146360 };
3813847Seh146360 
3823847Seh146360 /*
3833847Seh146360  * structure for notification IPW2200_NOTIF_TYPE_AUTHENTICATION
3843847Seh146360  */
3853847Seh146360 struct ipw2200_notif_authentication {
3863847Seh146360 	uint8_t		state;
3873847Seh146360 #define	IPW2200_AUTH_FAIL	(0)
3883847Seh146360 #define	IPW2200_AUTH_SENT_1	(1)
3893847Seh146360 #define	IPW2200_AUTH_RECV_2	(2)
3903847Seh146360 #define	IPW2200_AUTH_SEQ1_PASS	(3)
3913847Seh146360 #define	IPW2200_AUTH_SEQ1_FAIL	(4)
3923847Seh146360 #define	IPW2200_AUTH_SUCCESS	(9)
3933847Seh146360 };
3943847Seh146360 
3953847Seh146360 /*
3963847Seh146360  * structure for notification IPW2200_NOTIF_TYPE_ASSOCIATION
3973847Seh146360  */
3983847Seh146360 struct ipw2200_notif_association {
3993847Seh146360 	uint8_t		state;
4003847Seh146360 #define	IPW2200_ASSOC_FAIL	(0)
4013847Seh146360 #define	IPW2200_ASSOC_SUCCESS	(12)
4023847Seh146360 	struct ieee80211_frame	frame;
4033847Seh146360 	uint16_t	capinfo;
4043847Seh146360 	uint16_t	status;
4053847Seh146360 	uint16_t	associd;
4063847Seh146360 };
4073847Seh146360 
4083847Seh146360 /*
4093847Seh146360  * structure for notification BACAON
4103847Seh146360  */
4113847Seh146360 struct ipw2200_notif_beacon_state {
4123847Seh146360 	uint32_t	state;
4133847Seh146360 #define	IPW2200_BEACON_MISS	(1)
4143847Seh146360 	uint32_t	number;
4153847Seh146360 };
4163847Seh146360 
4173847Seh146360 /*
4183847Seh146360  * structure for notification IPW2200_NOTIF_TYPE_SCAN_CHANNEL
4193847Seh146360  */
4203847Seh146360 struct ipw2200_notif_scan_channel {
4213847Seh146360 	uint8_t		nchan;
4223847Seh146360 	uint8_t		reserved[47];
4233847Seh146360 };
4243847Seh146360 
4253847Seh146360 /*
4263847Seh146360  * structure for notification IPW2200_NOTIF_TYPE_SCAN_COMPLETE
4273847Seh146360  */
4283847Seh146360 struct ipw2200_notif_scan_complete {
4293847Seh146360 	uint8_t		type;
4303847Seh146360 	uint8_t		nchan;
4313847Seh146360 	uint8_t		status;
4323847Seh146360 	uint8_t		reserved;
4333847Seh146360 };
4343847Seh146360 
4353847Seh146360 /*
4363847Seh146360  * received frame header
4373847Seh146360  */
4383847Seh146360 struct ipw2200_frame {
4393847Seh146360 	uint32_t	reserved1[2];
4403847Seh146360 	uint8_t		chan;
4413847Seh146360 	uint8_t		status;
4423847Seh146360 	uint8_t		rate;
4433847Seh146360 	uint8_t		rssi; /* receiver signal strength indicator */
4443847Seh146360 	uint8_t		agc; /* automatic gain control */
4453847Seh146360 	uint8_t		rssi_dbm;
4463847Seh146360 	uint16_t	signal;
4473847Seh146360 	uint16_t	noise;
4483847Seh146360 	uint8_t		antenna;
4493847Seh146360 	uint8_t		control;
4503847Seh146360 	uint8_t		reserved3[2];
4513847Seh146360 	uint16_t	len;
4523847Seh146360 };
4533847Seh146360 
4543847Seh146360 /*
4553847Seh146360  * header for transmission
4563847Seh146360  */
4573847Seh146360 struct ipw2200_tx_desc {
4583847Seh146360 	struct ipw2200_hdr	hdr;
4593847Seh146360 	uint32_t	reserved1;
4603847Seh146360 	uint8_t		station;
4613847Seh146360 	uint8_t		reserved2[3];
4623847Seh146360 	uint8_t		cmd;
4633847Seh146360 #define	IPW2200_DATA_CMD_TX		(0x0b)
4643847Seh146360 	uint8_t		seq;
4653847Seh146360 	uint16_t	len;
4663847Seh146360 	uint8_t		priority;
4673847Seh146360 	uint8_t		flags;
4683847Seh146360 #define	IPW2200_DATA_FLAG_SHPREAMBLE	(0x04)
4693847Seh146360 #define	IPW2200_DATA_FLAG_NO_WEP	(0x20)
4703847Seh146360 #define	IPW2200_DATA_FLAG_NEED_ACK	(0x80)
4713847Seh146360 	uint8_t		xflags;
4723847Seh146360 #define	IPW2200_DATA_XFLAG_QOS		(0x10)
4733847Seh146360 	uint8_t		wep_txkey;
4743847Seh146360 	uint8_t		wepkey[IEEE80211_KEYBUF_SIZE];
4753847Seh146360 	uint8_t		rate;
4763847Seh146360 	uint8_t		antenna;
4773847Seh146360 	uint8_t		reserved3[10];
4783847Seh146360 
4793847Seh146360 	struct ieee80211_frame_addr4 wh;
4803847Seh146360 	uint8_t		reserved4[2];
4813847Seh146360 	uint32_t	iv;
4823847Seh146360 	uint32_t	eiv;
4833847Seh146360 
4843847Seh146360 	uint32_t	nseg;
4853847Seh146360 #define	IPW2200_MAX_NSEG		(6)
4863847Seh146360 	uint32_t	seg_addr[IPW2200_MAX_NSEG];
4873847Seh146360 	uint16_t	seg_len[IPW2200_MAX_NSEG];
4883847Seh146360 };
4893847Seh146360 
4903847Seh146360 /*
4913847Seh146360  * command
4923847Seh146360  */
4933847Seh146360 struct ipw2200_cmd_desc {
4943847Seh146360 	struct ipw2200_hdr	hdr;
4953847Seh146360 	uint8_t			type;
4963847Seh146360 #define	IPW2200_CMD_ENABLE		(2)
4973847Seh146360 #define	IPW2200_CMD_SET_CONFIG		(6)
4983847Seh146360 #define	IPW2200_CMD_SET_ESSID		(8)
4993847Seh146360 #define	IPW2200_CMD_SET_MAC_ADDRESS	(11)
5003847Seh146360 #define	IPW2200_CMD_SET_RTS_THRESHOLD	(15)
5013847Seh146360 #define	IPW2200_CMD_SET_FRAG_THRESHOLD	(16)
5023847Seh146360 #define	IPW2200_CMD_SET_POWER_MODE	(17)
5033847Seh146360 #define	IPW2200_CMD_SET_WEP_KEY		(18)
5043847Seh146360 #define	IPW2200_CMD_SCAN		(20)
5053847Seh146360 #define	IPW2200_CMD_ASSOCIATE		(21)
5063847Seh146360 #define	IPW2200_CMD_SET_RATES		(22)
5073847Seh146360 #define	IPW2200_CMD_ABORT_SCAN		(23)
5083847Seh146360 #define	IPW2200_CMD_SET_WME_PARAMS	(25)
5093847Seh146360 #define	IPW2200_CMD_SCAN_EXT		(26)
5103847Seh146360 #define	IPW2200_CMD_SET_OPTIE		(31)
5113847Seh146360 #define	IPW2200_CMD_DISABLE		(33)
5123847Seh146360 #define	IPW2200_CMD_SET_IV		(34)
5133847Seh146360 #define	IPW2200_CMD_SET_TX_POWER	(35)
5143847Seh146360 #define	IPW2200_CMD_SET_SENSITIVITY	(42)
5153847Seh146360 #define	IPW2200_CMD_SET_WMEIE		(84)
5163847Seh146360 	uint8_t			len;
5173847Seh146360 	uint16_t		reserved;
5183847Seh146360 	uint8_t			data[120];
5193847Seh146360 };
5203847Seh146360 
5213847Seh146360 /*
5223847Seh146360  * node information (IBSS)
5233847Seh146360  */
5243847Seh146360 struct ipw2200_ibssnode {
5253847Seh146360 	uint8_t		bssid[IEEE80211_ADDR_LEN];
5263847Seh146360 	uint8_t		reserved[2];
5273847Seh146360 };
5283847Seh146360 
5293847Seh146360 /*
5303847Seh146360  * constants for 'mode' fields
5313847Seh146360  */
5323847Seh146360 #define	IPW2200_MODE_11A	(0)
5333847Seh146360 #define	IPW2200_MODE_11B	(1)
5343847Seh146360 #define	IPW2200_MODE_11G	(2)
5353847Seh146360 
5363847Seh146360 /*
5373847Seh146360  * macro for command IPW2200_CMD_SET_SENSITIVITY
5383847Seh146360  */
5393847Seh146360 #define	IPW2200_RSSIDBM2RAW(rssi)((rssi) - 112)
5403847Seh146360 
5413847Seh146360 /*
5423847Seh146360  * possible values for command IPW2200_CMD_SET_POWER_MODE
5433847Seh146360  */
5443847Seh146360 #define	IPW2200_POWER_MODE_CAM		(0)
5453847Seh146360 #define	IPW2200_POWER_MODE_PSP		(3)
5463847Seh146360 #define	IPW2200_POWER_MODE_MAX		(5)
5473847Seh146360 
5483847Seh146360 /*
5493847Seh146360  * structure for command IPW2200_CMD_SET_RATES
5503847Seh146360  */
5513847Seh146360 struct ipw2200_rateset {
5523847Seh146360 	uint8_t		mode;
5533847Seh146360 	uint8_t		nrates;
5543847Seh146360 	uint8_t		type;
5553847Seh146360 #define	IPW2200_RATESET_TYPE_NEGOCIATED	(0)
5563847Seh146360 #define	IPW2200_RATESET_TYPE_SUPPORTED	(1)
5573847Seh146360 	uint8_t		reserved;
5583847Seh146360 	uint8_t		rates[12];
5593847Seh146360 };
5603847Seh146360 
5613847Seh146360 /*
5623847Seh146360  * structure for command IPW2200_CMD_SET_TX_POWER
5633847Seh146360  */
5643847Seh146360 struct ipw2200_txpower {
5653847Seh146360 	uint8_t		nchan;
5663847Seh146360 	uint8_t		mode;
5673847Seh146360 	struct {
5683847Seh146360 		uint8_t	chan;
5693847Seh146360 		uint8_t power;
5703847Seh146360 #define	IPW2200_TXPOWER_MAX	(20)
5713847Seh146360 #define	IPW2200_TXPOWER_RATIO	(IEEE80211_TXPOWER_MAX / IPW2200_TXPOWER_MAX)
5723847Seh146360 	} chan[37];
5733847Seh146360 };
5743847Seh146360 
5753847Seh146360 /*
5763847Seh146360  * structure for command IPW2200_CMD_ASSOCIATE
5773847Seh146360  */
5783847Seh146360 struct ipw2200_associate {
5793847Seh146360 	uint8_t		chan;
5803847Seh146360 	uint8_t		auth;
5813847Seh146360 #define	IPW2200_AUTH_OPEN	(0)
5823847Seh146360 #define	IPW2200_AUTH_SHARED	(1)
5833847Seh146360 #define	IPW2200_AUTH_NONE	(3)
5843847Seh146360 	uint8_t		type;
5853847Seh146360 #define	IPW2200_HC_ASSOC	(0)
5863847Seh146360 #define	IPW2200_HC_REASSOC	(1)
5873847Seh146360 #define	IPW2200_HC_DISASSOC	(2)
5883847Seh146360 #define	IPW2200_HC_IBSS_START	(3)
5893847Seh146360 #define	IPW2200_HC_IBSS_RECONF	(4)
5903847Seh146360 #define	IPW2200_HC_DISASSOC_QUIET (5)
5913847Seh146360 	uint8_t		reserved1;
5923847Seh146360 	uint16_t	policy;
5933847Seh146360 #define	IPW2200_POLICY_WME	(1)
5943847Seh146360 #define	IPW2200_POLICY_WPA	(2)
5953847Seh146360 	uint8_t		plen;
5963847Seh146360 	uint8_t		mode;
5973847Seh146360 	uint8_t		bssid[IEEE80211_ADDR_LEN];
5983847Seh146360 	uint8_t		tstamp[8];
5993847Seh146360 
6003847Seh146360 	uint16_t	capinfo;
6013847Seh146360 	uint16_t	lintval;
6023847Seh146360 	uint16_t	intval;
6033847Seh146360 	uint8_t		dst[IEEE80211_ADDR_LEN];
6043847Seh146360 	uint32_t	reserved3;
6053847Seh146360 	uint16_t	reserved4;
6063847Seh146360 };
6073847Seh146360 
6083847Seh146360 #define	IPW2200_SCAN_CHANNELS	(54)
6093847Seh146360 
6103847Seh146360 /*
6113847Seh146360  * structure for command IPW2200_CMD_SCAN
6123847Seh146360  */
6133847Seh146360 struct ipw2200_scan {
6143847Seh146360 	uint8_t		type;
6153847Seh146360 #define	IPW2200_SCAN_TYPE_PASSIVE_STOP	(0) /* passive, stop on first beacon */
6163847Seh146360 #define	IPW2200_SCAN_TYPE_PASSIVE	(1) /* passive, full dwell on channel */
6173847Seh146360 #define	IPW2200_SCAN_TYPE_DIRECTED	(2) /* active, directed probe seq */
6183847Seh146360 #define	IPW2200_SCAN_TYPE_BROADCAST	(3) /* active, bcast probe seq */
6193847Seh146360 #define	IPW2200_SCAN_TYPE_BDIRECTED	(4) /* active, directed+bcast probe */
6203847Seh146360 #define	IPW2200_SCAN_TYPES		(5)
6213847Seh146360 	uint16_t	dwelltime;
6223847Seh146360 	uint8_t		channels[IPW2200_SCAN_CHANNELS];
6233847Seh146360 #define	IPW2200_CHAN_5GHZ	(0 << 6)
6243847Seh146360 #define	IPW2200_CHAN_2GHZ	(1 << 6)
6253847Seh146360 	uint8_t		reserved[3];
6263847Seh146360 };
6273847Seh146360 
6283847Seh146360 /*
6293847Seh146360  * structure for command IPW2200_CMD_SCAN_EXT
6303847Seh146360  */
6313847Seh146360 struct ipw2200_scan_ext {
6323847Seh146360 	uint32_t	full_scan_index;
6333847Seh146360 	uint8_t		channels[IPW2200_SCAN_CHANNELS];
6343847Seh146360 	uint8_t		scan_type[IPW2200_SCAN_CHANNELS/2];
6353847Seh146360 	uint8_t		reserved;
6363847Seh146360 	uint16_t	dwell_time[IPW2200_SCAN_TYPES];
6373847Seh146360 };
6383847Seh146360 
6393847Seh146360 /*
6403847Seh146360  * structure for command IPW2200_CMD_SET_CONFIGURATION
6413847Seh146360  */
6423847Seh146360 struct ipw2200_configuration {
6433847Seh146360 	uint8_t		bluetooth_coexistence;
6443847Seh146360 	uint8_t		reserved1;
6453847Seh146360 	uint8_t		answer_pbreq;
6463847Seh146360 	uint8_t		allow_invalid_frames;
6473847Seh146360 	uint8_t		multicast_enabled;
6483847Seh146360 	uint8_t		drop_unicast_unencrypted;
6493847Seh146360 	uint8_t		disable_unicast_decryption;
6503847Seh146360 	uint8_t		drop_multicast_unencrypted;
6513847Seh146360 	uint8_t		disable_multicast_decryption;
6523847Seh146360 	uint8_t		antenna;
6533847Seh146360 #define	IPW2200_ANTENNA_AUTO	(0)	/* firmware selects best antenna */
6543847Seh146360 #define	IPW2200_ANTENNA_A	(1)	/* use antenna A only */
6553847Seh146360 #define	IPW2200_ANTENNA_B	(3)	/* use antenna B only */
6563847Seh146360 #define	IPW2200_ANTENNA_SLOWDIV	(2)	/* slow diversity algorithm */
6573847Seh146360 	uint8_t		include_crc;
6583847Seh146360 	uint8_t		use_protection;
6593847Seh146360 	uint8_t		protection_ctsonly;
6603847Seh146360 	uint8_t		enable_multicast_filtering;
6613847Seh146360 	uint8_t		bluetooth_threshold;
6623847Seh146360 	uint8_t		reserved4;
6633847Seh146360 	uint8_t		allow_beacon_and_probe_resp;
6643847Seh146360 	uint8_t		allow_mgt;
6653847Seh146360 	uint8_t		noise_reported;
6663847Seh146360 	uint8_t		reserved5;
6673847Seh146360 };
6683847Seh146360 
6693847Seh146360 /*
6703847Seh146360  * structure for command IPW2200_CMD_SET_WEP_KEY
6713847Seh146360  */
6723847Seh146360 struct ipw2200_wep_key {
6733847Seh146360 	uint8_t		cmd;
6743847Seh146360 #define	IPW2200_WEP_KEY_CMD_SETKEY	(0x08)
6753847Seh146360 	uint8_t		seq;
6763847Seh146360 	uint8_t		idx;
6773847Seh146360 	uint8_t		len;
6783847Seh146360 	uint8_t		key[IEEE80211_KEYBUF_SIZE];
6793847Seh146360 };
6803847Seh146360 
6813847Seh146360 /*
6823847Seh146360  * the following two structures are for future WME support
6833847Seh146360  */
6843847Seh146360 struct ipw2200_wme_params {
6853847Seh146360 	uint16_t	cwmin[WME_NUM_AC];
6863847Seh146360 	uint16_t	cwmax[WME_NUM_AC];
6873847Seh146360 	uint8_t		aifsn[WME_NUM_AC];
6883847Seh146360 	uint8_t		acm[WME_NUM_AC];
6893847Seh146360 	uint16_t	burst[WME_NUM_AC];
6903847Seh146360 };
6913847Seh146360 
6923847Seh146360 struct ipw2200_sensitivity {
6933847Seh146360 	uint16_t	rssi;
6943847Seh146360 #define	IPW2200_RSSI_TO_DBM	(112)
6953847Seh146360 	uint16_t	reserved;
6963847Seh146360 };
6973847Seh146360 
6983847Seh146360 #pragma pack()
6993847Seh146360 
7003847Seh146360 /*
7013847Seh146360  * ROM entries
7023847Seh146360  */
7033847Seh146360 #define	IPW2200_EEPROM_MAC	(0x21)
7043847Seh146360 #define	IPW2200_EEPROM_NIC	(0x25)	/* nic type (lsb) */
7053847Seh146360 #define	IPW2200_EEPROM_SKU	(0x25)	/* nic type (msb) */
7063847Seh146360 
7073847Seh146360 /*
7083847Seh146360  * EVENT controls
7093847Seh146360  */
7103847Seh146360 #define	IPW2200_IMEM_EVENT_CTL	(0x00300004)
7113847Seh146360 /*
7123847Seh146360  * EEPROM controls
7133847Seh146360  */
7143847Seh146360 #define	IPW2200_IMEM_EEPROM_CTL	(0x00300040)
7153847Seh146360 
7163847Seh146360 #define	IPW2200_EEPROM_DELAY	(1) /* minimum hold time(microsecond) */
7173847Seh146360 
7183847Seh146360 /*
7193847Seh146360  * possible flags for register IWI_MEM_EVENT
7203847Seh146360  */
7213847Seh146360 #define	IPW2200_LED_ASSOC	(1 << 5)
7223847Seh146360 #define	IPW2200_LED_MASK	(0xd9fffffb)
7233847Seh146360 
7243847Seh146360 /*
7253847Seh146360  * control and status registers access macros
7263847Seh146360  */
7273847Seh146360 extern uint8_t ipw2200_csr_get8(struct ipw2200_softc *sc, uint32_t off);
7283847Seh146360 extern uint16_t ipw2200_csr_get16(struct ipw2200_softc *sc, uint32_t off);
7293847Seh146360 extern uint32_t ipw2200_csr_get32(struct ipw2200_softc *sc, uint32_t off);
7303847Seh146360 extern void ipw2200_csr_getbuf32(struct ipw2200_softc *sc, uint32_t off,
7313847Seh146360     uint32_t *buf, size_t cnt);
7323847Seh146360 extern void ipw2200_csr_put8(struct ipw2200_softc *sc, uint32_t off,
7333847Seh146360     uint8_t val);
7343847Seh146360 extern void ipw2200_csr_put16(struct ipw2200_softc *sc, uint32_t off,
7353847Seh146360     uint16_t val);
7363847Seh146360 extern void ipw2200_csr_put32(struct ipw2200_softc *sc, uint32_t off,
7373847Seh146360     uint32_t val);
7383847Seh146360 /*
7393847Seh146360  * indirect memory space access macros
7403847Seh146360  */
7413847Seh146360 extern uint8_t ipw2200_imem_get8(struct ipw2200_softc *sc, uint32_t addr);
7423847Seh146360 extern uint16_t ipw2200_imem_get16(struct ipw2200_softc *sc,
7433847Seh146360     uint32_t addr);
7443847Seh146360 extern uint32_t ipw2200_imem_get32(struct ipw2200_softc *sc,
7453847Seh146360     uint32_t addr);
7463847Seh146360 extern void ipw2200_imem_put8(struct ipw2200_softc *sc, uint32_t addr,
7473847Seh146360     uint8_t val);
7483847Seh146360 extern void ipw2200_imem_put16(struct ipw2200_softc *sc, uint32_t addr,
7493847Seh146360     uint16_t val);
7503847Seh146360 extern void ipw2200_imem_put32(struct ipw2200_softc *sc, uint32_t addr,
7513847Seh146360     uint32_t val);
7523847Seh146360 /*
7533847Seh146360  * EEPROM access macro
7543847Seh146360  */
7553847Seh146360 extern void ipw2200_rom_control(struct ipw2200_softc *sc, uint32_t val);
7563847Seh146360 extern uint16_t ipw2200_rom_get16(struct ipw2200_softc *sc, uint8_t addr);
7573847Seh146360 
7583847Seh146360 /*
7593847Seh146360  * Firmware related definations and interfaces.
7603847Seh146360  */
7613847Seh146360 extern int ipw2200_cache_firmware(struct ipw2200_softc *sc);
7623847Seh146360 extern int ipw2200_free_firmware(struct ipw2200_softc *sc);
7633847Seh146360 extern int ipw2200_load_uc(struct ipw2200_softc *sc, uint8_t *buf, size_t size);
7643847Seh146360 extern int ipw2200_load_fw(struct ipw2200_softc *sc, uint8_t *buf, size_t size);
7653847Seh146360 
7663847Seh146360 #ifdef __cplusplus
7673847Seh146360 }
7683847Seh146360 #endif
7693847Seh146360 
7703847Seh146360 #endif /* _SYS_IPW2200_IMPL_H */
771