/* $OpenBSD: if_upgtvar.h,v 1.14 2008/02/02 13:48:44 mglocker Exp $ */ /* $FreeBSD$ */ /* * Copyright (c) 2007 Marcus Glocker * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ struct upgt_softc; /* * General values. */ enum { UPGT_BULK_RX, UPGT_BULK_TX, UPGT_N_XFERS = 2, }; #define UPGT_CONFIG_INDEX 0 #define UPGT_IFACE_INDEX 0 #define UPGT_USB_TIMEOUT 1000 #define UPGT_FIRMWARE_TIMEOUT 10 #define UPGT_MEMADDR_FIRMWARE_START 0x00020000 /* 512 bytes large */ #define UPGT_MEMSIZE_FRAME_HEAD 0x0070 #define UPGT_MEMSIZE_RX 0x3500 #define UPGT_RX_MAXCOUNT 6 #define UPGT_TX_MAXCOUNT 128 #define UPGT_TX_STAT_INTERVAL 5 #define UPGT_RX_MINSZ (sizeof(struct upgt_lmac_header) + 4) /* device flags */ #define UPGT_DEVICE_ATTACHED (1 << 0) /* leds */ #define UPGT_LED_OFF 0 #define UPGT_LED_ON 1 #define UPGT_LED_BLINK 2 /* * Firmware. */ #define UPGT_FW_BLOCK_SIZE 256 #define UPGT_BRA_FWTYPE_SIZE 4 #define UPGT_BRA_FWTYPE_LM86 "LM86" #define UPGT_BRA_FWTYPE_LM87 "LM87" enum upgt_fw_type { UPGT_FWTYPE_LM86, UPGT_FWTYPE_LM87 }; #define UPGT_BRA_TYPE_FW 0x80000001 #define UPGT_BRA_TYPE_VERSION 0x80000002 #define UPGT_BRA_TYPE_DEPIF 0x80000003 #define UPGT_BRA_TYPE_EXPIF 0x80000004 #define UPGT_BRA_TYPE_DESCR 0x80000101 #define UPGT_BRA_TYPE_END 0xff0000ff struct upgt_fw_bra_option { uint32_t type; uint32_t len; uint8_t data[]; } __packed; struct upgt_fw_bra_descr { uint32_t unknown1; uint32_t memaddr_space_start; uint32_t memaddr_space_end; uint32_t unknown2; uint32_t unknown3; uint8_t rates[20]; } __packed; #define UPGT_X2_SIGNATURE_SIZE 4 #define UPGT_X2_SIGNATURE "x2 " struct upgt_fw_x2_header { uint8_t signature[4]; uint32_t startaddr; uint32_t len; uint32_t crc; } __packed; /* * EEPROM. */ #define UPGT_EEPROM_SIZE 8192 #define UPGT_EEPROM_BLOCK_SIZE 1020 struct upgt_eeprom_header { /* 14 bytes */ uint32_t magic; uint16_t pad1; uint16_t preamble_len; uint32_t pad2; /* data */ } __packed; #define UPGT_EEPROM_TYPE_END 0x0000 #define UPGT_EEPROM_TYPE_NAME 0x0001 #define UPGT_EEPROM_TYPE_SERIAL 0x0003 #define UPGT_EEPROM_TYPE_MAC 0x0101 #define UPGT_EEPROM_TYPE_HWRX 0x1001 #define UPGT_EEPROM_TYPE_CHIP 0x1002 #define UPGT_EEPROM_TYPE_FREQ3 0x1903 #define UPGT_EEPROM_TYPE_FREQ4 0x1904 #define UPGT_EEPROM_TYPE_FREQ5 0x1905 #define UPGT_EEPROM_TYPE_FREQ6 0x1906 #define UPGT_EEPROM_TYPE_OFF 0xffff struct upgt_eeprom_option { uint16_t len; uint16_t type; uint8_t data[]; /* data */ } __packed; #define UPGT_EEPROM_RX_CONST 0x88 struct upgt_eeprom_option_hwrx { uint32_t pad1; uint8_t rxfilter; uint8_t pad2[15]; } __packed; struct upgt_eeprom_freq3_header { uint8_t flags; uint8_t elements; } __packed; struct upgt_eeprom_freq4_header { uint8_t flags; uint8_t elements; uint8_t settings; uint8_t type; } __packed; struct upgt_eeprom_freq4_1 { uint16_t freq; uint8_t data[50]; } __packed; struct upgt_eeprom_freq4_2 { uint16_t head; uint8_t subtails[4]; uint8_t tail; } __packed; /* * LMAC protocol. */ struct upgt_lmac_mem { uint32_t addr; uint32_t chksum; } __packed; #define UPGT_H1_FLAGS_TX_MGMT 0x00 /* for TX: mgmt frame */ #define UPGT_H1_FLAGS_TX_NO_CALLBACK 0x01 /* for TX: no USB callback */ #define UPGT_H1_FLAGS_TX_DATA 0x10 /* for TX: data frame */ #define UPGT_H1_TYPE_RX_DATA 0x00 /* 802.11 RX data frame */ #define UPGT_H1_TYPE_RX_DATA_MGMT 0x04 /* 802.11 RX mgmt frame */ #define UPGT_H1_TYPE_TX_DATA 0x40 /* 802.11 TX data frame */ #define UPGT_H1_TYPE_CTRL 0x80 /* control frame */ struct upgt_lmac_h1 { /* 4 bytes */ uint8_t flags; uint8_t type; uint16_t len; } __packed; #define UPGT_H2_TYPE_TX_ACK_NO 0x0000 #define UPGT_H2_TYPE_TX_ACK_YES 0x0001 #define UPGT_H2_TYPE_MACFILTER 0x0000 #define UPGT_H2_TYPE_CHANNEL 0x0001 #define UPGT_H2_TYPE_TX_DONE 0x0008 #define UPGT_H2_TYPE_STATS 0x000a #define UPGT_H2_TYPE_EEPROM 0x000c #define UPGT_H2_TYPE_LED 0x000d #define UPGT_H2_FLAGS_TX_ACK_NO 0x0101 #define UPGT_H2_FLAGS_TX_ACK_YES 0x0707 struct upgt_lmac_h2 { /* 8 bytes */ uint32_t reqid; uint16_t type; uint16_t flags; } __packed; struct upgt_lmac_header { /* 12 bytes */ struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; } __packed; struct upgt_lmac_eeprom { /* 16 bytes */ struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; uint16_t offset; uint16_t len; /* data */ } __packed; #define UPGT_FILTER_TYPE_NONE 0x0000 #define UPGT_FILTER_TYPE_STA 0x0001 #define UPGT_FILTER_TYPE_IBSS 0x0002 #define UPGT_FILTER_TYPE_HOSTAP 0x0004 #define UPGT_FILTER_TYPE_MONITOR 0x0010 #define UPGT_FILTER_TYPE_RESET 0x0020 #define UPGT_FILTER_UNKNOWN1 0x0002 #define UPGT_FILTER_UNKNOWN2 0x0ca8 #define UPGT_FILTER_UNKNOWN3 0xffff #define UPGT_FILTER_MONITOR_UNKNOWN1 0x0000 #define UPGT_FILTER_MONITOR_UNKNOWN2 0x0000 #define UPGT_FILTER_MONITOR_UNKNOWN3 0x0000 struct upgt_lmac_filter { struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; /* 32 bytes */ uint16_t type; uint8_t dst[IEEE80211_ADDR_LEN]; uint8_t src[IEEE80211_ADDR_LEN]; uint16_t unknown1; uint32_t rxaddr; uint16_t unknown2; uint32_t rxhw; uint16_t unknown3; uint32_t unknown4; } __packed; /* frequence 3 data */ struct upgt_lmac_freq3 { uint16_t freq; uint8_t data[6]; } __packed; /* frequence 4 data */ struct upgt_lmac_freq4 { struct upgt_eeprom_freq4_2 cmd; uint8_t pad; }; /* frequence 6 data */ struct upgt_lmac_freq6 { uint16_t freq; uint8_t data[8]; } __packed; #define UPGT_CHANNEL_UNKNOWN1 0x0001 #define UPGT_CHANNEL_UNKNOWN2 0x0000 #define UPGT_CHANNEL_UNKNOWN3 0x48 struct upgt_lmac_channel { struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; /* 112 bytes */ uint16_t unknown1; uint16_t unknown2; uint8_t pad1[20]; struct upgt_lmac_freq6 freq6; uint8_t settings; uint8_t unknown3; uint8_t freq3_1[4]; struct upgt_lmac_freq4 freq4[8]; uint8_t freq3_2[4]; uint32_t pad2; } __packed; #define UPGT_LED_MODE_SET 0x0003 #define UPGT_LED_ACTION_OFF 0x0002 #define UPGT_LED_ACTION_ON 0x0003 #define UPGT_LED_ACTION_TMP_DUR 100 /* ms */ struct upgt_lmac_led { struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; uint16_t mode; uint16_t action_fix; uint16_t action_tmp; uint16_t action_tmp_dur; } __packed; struct upgt_lmac_stats { struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; uint8_t data[76]; } __packed; struct upgt_lmac_rx_desc { struct upgt_lmac_h1 header1; /* 16 bytes */ uint16_t freq; uint8_t unknown1; uint8_t rate; uint8_t rssi; uint8_t pad; uint16_t unknown2; uint32_t timestamp; uint32_t unknown3; uint8_t data[]; } __packed; #define UPGT_TX_DESC_KEY_EXISTS 0x01 struct upgt_lmac_tx_desc_wep { uint8_t key_exists; uint8_t key_len; uint8_t key_val[16]; } __packed; #define UPGT_TX_DESC_TYPE_BEACON 0x00000000 #define UPGT_TX_DESC_TYPE_PROBE 0x00000001 #define UPGT_TX_DESC_TYPE_MGMT 0x00000002 #define UPGT_TX_DESC_TYPE_DATA 0x00000004 #define UPGT_TX_DESC_PAD3_SIZE 2 struct upgt_lmac_tx_desc { struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; uint8_t rates[8]; uint16_t pad1; struct upgt_lmac_tx_desc_wep wep_key; uint32_t type; uint32_t pad2; uint32_t unknown1; uint32_t unknown2; uint8_t pad3[2]; /* 802.11 frame data */ } __packed; #define UPGT_TX_DONE_DESC_STATUS_OK 0x0001 struct upgt_lmac_tx_done_desc { struct upgt_lmac_h1 header1; struct upgt_lmac_h2 header2; uint16_t status; uint16_t rssi; uint16_t seq; uint16_t unknown; } __packed; /* * USB xfers. */ struct upgt_data { uint8_t *buf; uint32_t buflen; struct ieee80211_node *ni; struct mbuf *m; uint32_t addr; uint8_t use; STAILQ_ENTRY(upgt_data) next; }; typedef STAILQ_HEAD(, upgt_data) upgt_datahead; /* * Prism memory. */ struct upgt_memory_page { uint8_t used; uint32_t addr; } __packed; #define UPGT_MEMORY_MAX_PAGES 8 struct upgt_memory { uint8_t pages; struct upgt_memory_page page[UPGT_MEMORY_MAX_PAGES]; } __packed; /* * BPF */ struct upgt_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; uint8_t wr_flags; uint8_t wr_rate; uint16_t wr_chan_freq; uint16_t wr_chan_flags; int8_t wr_antsignal; } __packed; #define UPGT_RX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) struct upgt_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; uint8_t wt_flags; uint8_t wt_rate; uint16_t wt_chan_freq; uint16_t wt_chan_flags; } __packed; #define UPGT_TX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL)) struct upgt_stat { uint32_t st_tx_active; uint32_t st_tx_inactive; uint32_t st_tx_pending; }; #define UPGT_STAT_INC(sc, var) (sc)->sc_stat.var++ #define UPGT_STAT_DEC(sc, var) (sc)->sc_stat.var-- struct upgt_vap { struct ieee80211vap vap; int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); }; #define UPGT_VAP(vap) ((struct upgt_vap *)(vap)) struct upgt_softc { device_t sc_dev; struct ifnet *sc_ifp; struct usb_device *sc_udev; void *sc_rx_dma_buf; void *sc_tx_dma_buf; struct mtx sc_mtx; struct upgt_stat sc_stat; int sc_flags; #define UPGT_FLAG_FWLOADED (1 << 0) #define UPGT_FLAG_INITDONE (1 << 1) int sc_if_flags; int sc_debug; uint8_t sc_myaddr[IEEE80211_ADDR_LEN]; enum ieee80211_state sc_state; int sc_arg; int sc_led_blink; struct callout sc_led_ch; uint8_t sc_cur_rateset[8]; /* watchdog */ int sc_tx_timer; struct callout sc_watchdog_ch; /* Firmware. */ int sc_fw_type; /* memory addresses on device */ uint32_t sc_memaddr_frame_start; uint32_t sc_memaddr_frame_end; uint32_t sc_memaddr_rx_start; struct upgt_memory sc_memory; /* data which we found in the EEPROM */ uint8_t sc_eeprom[UPGT_EEPROM_SIZE]; uint16_t sc_eeprom_hwrx; struct upgt_lmac_freq3 sc_eeprom_freq3[IEEE80211_CHAN_MAX]; struct upgt_lmac_freq4 sc_eeprom_freq4[IEEE80211_CHAN_MAX][8]; struct upgt_lmac_freq6 sc_eeprom_freq6[IEEE80211_CHAN_MAX]; uint8_t sc_eeprom_freq6_settings; /* RX/TX */ struct usb_xfer *sc_xfer[UPGT_N_XFERS]; int sc_rx_no; int sc_tx_no; struct upgt_data sc_rx_data[UPGT_RX_MAXCOUNT]; upgt_datahead sc_rx_active; upgt_datahead sc_rx_inactive; struct upgt_data sc_tx_data[UPGT_TX_MAXCOUNT]; upgt_datahead sc_tx_active; upgt_datahead sc_tx_inactive; upgt_datahead sc_tx_pending; /* BPF */ struct upgt_rx_radiotap_header sc_rxtap; int sc_rxtap_len; struct upgt_tx_radiotap_header sc_txtap; int sc_txtap_len; }; #define UPGT_LOCK(sc) mtx_lock(&(sc)->sc_mtx) #define UPGT_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) #define UPGT_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)