1*d0c50e91SJohannes Hofmann /* $FreeBSD$ */ 24db7dd1bSJoe Talbott 34db7dd1bSJoe Talbott /*- 44db7dd1bSJoe Talbott * Copyright (c) 2006,2007 54db7dd1bSJoe Talbott * Damien Bergamini <damien.bergamini@free.fr> 64db7dd1bSJoe Talbott * 74db7dd1bSJoe Talbott * Permission to use, copy, modify, and distribute this software for any 84db7dd1bSJoe Talbott * purpose with or without fee is hereby granted, provided that the above 94db7dd1bSJoe Talbott * copyright notice and this permission notice appear in all copies. 104db7dd1bSJoe Talbott * 114db7dd1bSJoe Talbott * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 124db7dd1bSJoe Talbott * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 134db7dd1bSJoe Talbott * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 144db7dd1bSJoe Talbott * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 154db7dd1bSJoe Talbott * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 164db7dd1bSJoe Talbott * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 174db7dd1bSJoe Talbott * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 184db7dd1bSJoe Talbott */ 194db7dd1bSJoe Talbott #include <netproto/802_11/ieee80211_amrr.h> 204db7dd1bSJoe Talbott 214db7dd1bSJoe Talbott struct wpi_rx_radiotap_header { 224db7dd1bSJoe Talbott struct ieee80211_radiotap_header wr_ihdr; 234db7dd1bSJoe Talbott uint64_t wr_tsft; 244db7dd1bSJoe Talbott uint8_t wr_flags; 254db7dd1bSJoe Talbott uint8_t wr_rate; 264db7dd1bSJoe Talbott uint16_t wr_chan_freq; 274db7dd1bSJoe Talbott uint16_t wr_chan_flags; 284db7dd1bSJoe Talbott int8_t wr_dbm_antsignal; 294db7dd1bSJoe Talbott int8_t wr_dbm_antnoise; 304db7dd1bSJoe Talbott uint8_t wr_antenna; 314db7dd1bSJoe Talbott }; 324db7dd1bSJoe Talbott 334db7dd1bSJoe Talbott #define WPI_RX_RADIOTAP_PRESENT \ 344db7dd1bSJoe Talbott ((1 << IEEE80211_RADIOTAP_TSFT) | \ 354db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_FLAGS) | \ 364db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_RATE) | \ 374db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 384db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 394db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 404db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_ANTENNA)) 414db7dd1bSJoe Talbott 424db7dd1bSJoe Talbott struct wpi_tx_radiotap_header { 434db7dd1bSJoe Talbott struct ieee80211_radiotap_header wt_ihdr; 444db7dd1bSJoe Talbott uint8_t wt_flags; 454db7dd1bSJoe Talbott uint8_t wt_rate; 464db7dd1bSJoe Talbott uint16_t wt_chan_freq; 474db7dd1bSJoe Talbott uint16_t wt_chan_flags; 484db7dd1bSJoe Talbott uint8_t wt_hwqueue; 494db7dd1bSJoe Talbott }; 504db7dd1bSJoe Talbott 514db7dd1bSJoe Talbott #define WPI_TX_RADIOTAP_PRESENT \ 524db7dd1bSJoe Talbott ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 534db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_RATE) | \ 544db7dd1bSJoe Talbott (1 << IEEE80211_RADIOTAP_CHANNEL)) 554db7dd1bSJoe Talbott 564db7dd1bSJoe Talbott struct wpi_dma_info { 574db7dd1bSJoe Talbott bus_dma_tag_t tag; 584db7dd1bSJoe Talbott bus_dmamap_t map; 594db7dd1bSJoe Talbott bus_addr_t paddr; /* aligned p address */ 604db7dd1bSJoe Talbott bus_addr_t paddr_start; /* possibly unaligned p start*/ 614db7dd1bSJoe Talbott caddr_t vaddr; /* aligned v address */ 624db7dd1bSJoe Talbott caddr_t vaddr_start; /* possibly unaligned v start */ 634db7dd1bSJoe Talbott bus_size_t size; 644db7dd1bSJoe Talbott }; 654db7dd1bSJoe Talbott 664db7dd1bSJoe Talbott struct wpi_tx_data { 674db7dd1bSJoe Talbott bus_dmamap_t map; 684db7dd1bSJoe Talbott struct mbuf *m; 694db7dd1bSJoe Talbott struct ieee80211_node *ni; 704db7dd1bSJoe Talbott }; 714db7dd1bSJoe Talbott 724db7dd1bSJoe Talbott struct wpi_tx_ring { 734db7dd1bSJoe Talbott struct wpi_dma_info desc_dma; 744db7dd1bSJoe Talbott struct wpi_dma_info cmd_dma; 754db7dd1bSJoe Talbott struct wpi_tx_desc *desc; 764db7dd1bSJoe Talbott struct wpi_tx_cmd *cmd; 774db7dd1bSJoe Talbott struct wpi_tx_data *data; 784db7dd1bSJoe Talbott bus_dma_tag_t data_dmat; 794db7dd1bSJoe Talbott int qid; 804db7dd1bSJoe Talbott int count; 814db7dd1bSJoe Talbott int queued; 824db7dd1bSJoe Talbott int cur; 834db7dd1bSJoe Talbott }; 844db7dd1bSJoe Talbott 854db7dd1bSJoe Talbott #define WPI_RBUF_COUNT ( WPI_RX_RING_COUNT + 16 ) 864db7dd1bSJoe Talbott 874db7dd1bSJoe Talbott struct wpi_rx_data { 884db7dd1bSJoe Talbott bus_dmamap_t map; 894db7dd1bSJoe Talbott struct mbuf *m; 904db7dd1bSJoe Talbott }; 914db7dd1bSJoe Talbott 924db7dd1bSJoe Talbott struct wpi_rx_ring { 934db7dd1bSJoe Talbott struct wpi_dma_info desc_dma; 944db7dd1bSJoe Talbott uint32_t *desc; 954db7dd1bSJoe Talbott struct wpi_rx_data data[WPI_RX_RING_COUNT]; 964db7dd1bSJoe Talbott bus_dma_tag_t data_dmat; 974db7dd1bSJoe Talbott int cur; 984db7dd1bSJoe Talbott }; 994db7dd1bSJoe Talbott 1004db7dd1bSJoe Talbott struct wpi_amrr { 1014db7dd1bSJoe Talbott struct ieee80211_node ni; /* must be the first */ 1024db7dd1bSJoe Talbott int txcnt; 1034db7dd1bSJoe Talbott int retrycnt; 1044db7dd1bSJoe Talbott int success; 1054db7dd1bSJoe Talbott int success_threshold; 1064db7dd1bSJoe Talbott int recovery; 1074db7dd1bSJoe Talbott }; 1084db7dd1bSJoe Talbott 1094db7dd1bSJoe Talbott struct wpi_power_sample { 1104db7dd1bSJoe Talbott uint8_t index; 1114db7dd1bSJoe Talbott int8_t power; 1124db7dd1bSJoe Talbott }; 1134db7dd1bSJoe Talbott 1144db7dd1bSJoe Talbott struct wpi_power_group { 1154db7dd1bSJoe Talbott #define WPI_SAMPLES_COUNT 5 1164db7dd1bSJoe Talbott struct wpi_power_sample samples[WPI_SAMPLES_COUNT]; 1174db7dd1bSJoe Talbott uint8_t chan; 1184db7dd1bSJoe Talbott int8_t maxpwr; 1194db7dd1bSJoe Talbott int16_t temp; 1204db7dd1bSJoe Talbott }; 1214db7dd1bSJoe Talbott 1224db7dd1bSJoe Talbott struct wpi_vap { 1234db7dd1bSJoe Talbott struct ieee80211vap vap; 1244db7dd1bSJoe Talbott 1254db7dd1bSJoe Talbott int (*newstate)(struct ieee80211vap *, 1264db7dd1bSJoe Talbott enum ieee80211_state, int); 1274db7dd1bSJoe Talbott }; 1284db7dd1bSJoe Talbott #define WPI_VAP(vap) ((struct wpi_vap *)(vap)) 1294db7dd1bSJoe Talbott 1304db7dd1bSJoe Talbott struct wpi_softc { 131dad604b8SJoe Talbott device_t sc_dev; 132*d0c50e91SJohannes Hofmann struct ifnet *sc_ifp; 133*d0c50e91SJohannes Hofmann struct lock sc_mtx; 1344db7dd1bSJoe Talbott 1354db7dd1bSJoe Talbott /* Flags indicating the current state the driver 1364db7dd1bSJoe Talbott * expects the hardware to be in 1374db7dd1bSJoe Talbott */ 1384db7dd1bSJoe Talbott uint32_t flags; 1394db7dd1bSJoe Talbott #define WPI_FLAG_HW_RADIO_OFF (1 << 0) 1404db7dd1bSJoe Talbott #define WPI_FLAG_BUSY (1 << 1) 1414db7dd1bSJoe Talbott #define WPI_FLAG_AUTH (1 << 2) 1424db7dd1bSJoe Talbott 1434db7dd1bSJoe Talbott /* shared area */ 1444db7dd1bSJoe Talbott struct wpi_dma_info shared_dma; 1454db7dd1bSJoe Talbott struct wpi_shared *shared; 1464db7dd1bSJoe Talbott 1474db7dd1bSJoe Talbott struct wpi_tx_ring txq[WME_NUM_AC]; 1484db7dd1bSJoe Talbott struct wpi_tx_ring cmdq; 1494db7dd1bSJoe Talbott struct wpi_rx_ring rxq; 1504db7dd1bSJoe Talbott 1514db7dd1bSJoe Talbott /* TX Thermal Callibration */ 152*d0c50e91SJohannes Hofmann struct callout calib_to; 1534db7dd1bSJoe Talbott int calib_cnt; 1544db7dd1bSJoe Talbott 1554db7dd1bSJoe Talbott /* Watch dog timer */ 156*d0c50e91SJohannes Hofmann struct callout watchdog_to; 1574db7dd1bSJoe Talbott /* Hardware switch polling timer */ 158*d0c50e91SJohannes Hofmann struct callout hwswitch_to; 1594db7dd1bSJoe Talbott 1604db7dd1bSJoe Talbott struct resource *irq; 1614db7dd1bSJoe Talbott struct resource *mem; 1624db7dd1bSJoe Talbott bus_space_tag_t sc_st; 1634db7dd1bSJoe Talbott bus_space_handle_t sc_sh; 1644db7dd1bSJoe Talbott void *sc_ih; 1654db7dd1bSJoe Talbott 1664db7dd1bSJoe Talbott struct wpi_config config; 1674db7dd1bSJoe Talbott int temp; 1684db7dd1bSJoe Talbott 1694db7dd1bSJoe Talbott 1704db7dd1bSJoe Talbott int sc_tx_timer; 1714db7dd1bSJoe Talbott int sc_scan_timer; 1724db7dd1bSJoe Talbott 1734db7dd1bSJoe Talbott struct bpf_if *sc_drvbpf; 1744db7dd1bSJoe Talbott 1754db7dd1bSJoe Talbott struct wpi_rx_radiotap_header sc_rxtap; 1764db7dd1bSJoe Talbott struct wpi_tx_radiotap_header sc_txtap; 1774db7dd1bSJoe Talbott 1784db7dd1bSJoe Talbott /* firmware image */ 1794db7dd1bSJoe Talbott const struct firmware *fw_fp; 1804db7dd1bSJoe Talbott 1814db7dd1bSJoe Talbott /* firmware DMA transfer */ 1824db7dd1bSJoe Talbott struct wpi_dma_info fw_dma; 1834db7dd1bSJoe Talbott 1844db7dd1bSJoe Talbott /* Tasks used by the driver */ 1854db7dd1bSJoe Talbott struct task sc_restarttask; /* reset firmware task */ 1864db7dd1bSJoe Talbott struct task sc_radiotask; /* reset rf task */ 1874db7dd1bSJoe Talbott 1884db7dd1bSJoe Talbott /* Eeprom info */ 1894db7dd1bSJoe Talbott uint8_t cap; 1904db7dd1bSJoe Talbott uint16_t rev; 1914db7dd1bSJoe Talbott uint8_t type; 1924db7dd1bSJoe Talbott struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT]; 1934db7dd1bSJoe Talbott int8_t maxpwr[IEEE80211_CHAN_MAX]; 1944db7dd1bSJoe Talbott char domain[4]; /*reglatory domain XXX */ 1954db7dd1bSJoe Talbott }; 1961a657da7SJoe Talbott 197*d0c50e91SJohannes Hofmann #define WPI_LOCK_INIT(_sc) \ 198*d0c50e91SJohannes Hofmann lockinit(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), 0, 0) 199*d0c50e91SJohannes Hofmann #define WPI_LOCK(_sc) lockmgr(&(_sc)->sc_mtx, LK_EXCLUSIVE) 200*d0c50e91SJohannes Hofmann #define WPI_UNLOCK(_sc) lockmgr(&(_sc)->sc_mtx, LK_RELEASE) 201*d0c50e91SJohannes Hofmann #define WPI_LOCK_ASSERT(_sc) KKASSERT(lockstatus(&(_sc)->sc_mtx, curthread) == LK_EXCLUSIVE) 202*d0c50e91SJohannes Hofmann #define WPI_LOCK_DESTROY(_sc) lockuninit(&(_sc)->sc_mtx) 203*d0c50e91SJohannes Hofmann 204