iprowifi3945: Sync with FreeBSD 11.1.

Tested and verified as working by cocobean. (The previous driver KDLed
on their hardware.)
This commit is contained in:
Augustin Cavalier 2018-06-28 17:18:46 -04:00
parent dcf58b2783
commit 9552ec8248
6 changed files with 5746 additions and 3282 deletions

View File

@ -1,14 +1,14 @@
SubDir HAIKU_TOP src add-ons kernel drivers network wlan iprowifi3945 ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ]
: true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_wlan ] : true ;
UsePrivateHeaders net system ;
UsePrivateKernelHeaders ;
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 _XOPEN_SOURCE ]
-Wno-format
-Wno-unused
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 _XOPEN_SOURCE ]
-Wno-format
-Wno-unused
-Wno-uninitialized ;
UseHeaders [ FDirName $(SUBDIR) ] : true ;
@ -19,8 +19,8 @@ KernelAddon iprowifi3945 :
if_wpi.c
glue.c
:
libfreebsd_wlan.a
libfreebsd_network.a
libfreebsd11_wlan.a
libfreebsd11_network.a
;
HAIKU_WIFI_FIRMWARE_PACKAGE on iprowifi3945 = iwlwifi-3945-ucode-15.32.2.9 ;

View File

@ -0,0 +1,144 @@
/*-
* Copyright (c) 2006,2007
* Damien Bergamini <damien.bergamini@free.fr>
* Benjamin Close <Benjamin.Close@clearchain.com>
* Copyright (c) 2015 Andriy Voskoboinyk <avos@FreeBSD.org>
*
* 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.
*
* $FreeBSD: releng/11.1/sys/dev/wpi/if_wpi_debug.h 292176 2015-12-13 22:08:27Z avos $
*/
#ifndef __IF_WPI_DEBUG_H__
#define __IF_WPI_DEBUG_H__
#ifdef WPI_DEBUG
enum {
WPI_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
WPI_DEBUG_RECV = 0x00000002, /* basic recv operation */
WPI_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
WPI_DEBUG_HW = 0x00000008, /* Stage 1 (eeprom) debugging */
WPI_DEBUG_RESET = 0x00000010, /* reset processing */
WPI_DEBUG_FIRMWARE = 0x00000020, /* firmware(9) loading debug */
WPI_DEBUG_BEACON = 0x00000040, /* beacon handling */
WPI_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
WPI_DEBUG_INTR = 0x00000100, /* ISR */
WPI_DEBUG_SCAN = 0x00000200, /* Scan related operations */
WPI_DEBUG_NOTIFY = 0x00000400, /* State 2 Notif intr debug */
WPI_DEBUG_TEMP = 0x00000800, /* TXPower/Temp Calibration */
WPI_DEBUG_CMD = 0x00001000, /* cmd submission */
WPI_DEBUG_TRACE = 0x00002000, /* Print begin and start driver function */
WPI_DEBUG_PWRSAVE = 0x00004000, /* Power save operations */
WPI_DEBUG_EEPROM = 0x00008000, /* EEPROM info */
WPI_DEBUG_NODE = 0x00010000, /* node addition/removal */
WPI_DEBUG_KEY = 0x00020000, /* node key management */
WPI_DEBUG_EDCA = 0x00040000, /* WME info */
WPI_DEBUG_REGISTER = 0x00080000, /* print chipset register */
WPI_DEBUG_BMISS = 0x00100000, /* print number of missed beacons */
WPI_DEBUG_ANY = 0xffffffff
};
#define DPRINTF(sc, m, ...) do { \
if (sc->sc_debug & (m)) \
printf(__VA_ARGS__); \
} while (0)
#define TRACE_STR_BEGIN "->%s: begin\n"
#define TRACE_STR_DOING "->Doing %s\n"
#define TRACE_STR_END "->%s: end\n"
#define TRACE_STR_END_ERR "->%s: end in error\n"
#define WPI_DESC(x) case x: return #x
static const char *wpi_cmd_str(int cmd)
{
switch (cmd) {
/* Notifications. */
WPI_DESC(WPI_UC_READY);
WPI_DESC(WPI_RX_DONE);
WPI_DESC(WPI_START_SCAN);
WPI_DESC(WPI_SCAN_RESULTS);
WPI_DESC(WPI_STOP_SCAN);
WPI_DESC(WPI_BEACON_SENT);
WPI_DESC(WPI_RX_STATISTICS);
WPI_DESC(WPI_BEACON_STATISTICS);
WPI_DESC(WPI_STATE_CHANGED);
WPI_DESC(WPI_BEACON_MISSED);
/* Command notifications. */
WPI_DESC(WPI_CMD_RXON);
WPI_DESC(WPI_CMD_RXON_ASSOC);
WPI_DESC(WPI_CMD_EDCA_PARAMS);
WPI_DESC(WPI_CMD_TIMING);
WPI_DESC(WPI_CMD_ADD_NODE);
WPI_DESC(WPI_CMD_DEL_NODE);
WPI_DESC(WPI_CMD_TX_DATA);
WPI_DESC(WPI_CMD_MRR_SETUP);
WPI_DESC(WPI_CMD_SET_LED);
WPI_DESC(WPI_CMD_SET_POWER_MODE);
WPI_DESC(WPI_CMD_SCAN);
WPI_DESC(WPI_CMD_SCAN_ABORT);
WPI_DESC(WPI_CMD_SET_BEACON);
WPI_DESC(WPI_CMD_TXPOWER);
WPI_DESC(WPI_CMD_BT_COEX);
default:
return "UNKNOWN CMD";
}
}
/*
* Translate CSR code to string
*/
static const char *wpi_get_csr_string(size_t csr)
{
switch (csr) {
WPI_DESC(WPI_HW_IF_CONFIG);
WPI_DESC(WPI_INT);
WPI_DESC(WPI_INT_MASK);
WPI_DESC(WPI_FH_INT);
WPI_DESC(WPI_GPIO_IN);
WPI_DESC(WPI_RESET);
WPI_DESC(WPI_GP_CNTRL);
WPI_DESC(WPI_EEPROM);
WPI_DESC(WPI_EEPROM_GP);
WPI_DESC(WPI_GIO);
WPI_DESC(WPI_UCODE_GP1);
WPI_DESC(WPI_UCODE_GP2);
WPI_DESC(WPI_GIO_CHICKEN);
WPI_DESC(WPI_ANA_PLL);
WPI_DESC(WPI_DBG_HPET_MEM);
default:
KASSERT(0, ("Unknown CSR: %d\n", csr));
return "UNKNOWN CSR";
}
}
static const char *wpi_get_prph_string(size_t prph)
{
switch (prph) {
WPI_DESC(WPI_APMG_CLK_CTRL);
WPI_DESC(WPI_APMG_PS);
WPI_DESC(WPI_APMG_PCI_STT);
WPI_DESC(WPI_APMG_RFKILL);
default:
KASSERT(0, ("Unknown register: %d\n", prph));
return "UNKNOWN PRPH";
}
}
#else
#define DPRINTF(sc, m, ...) do { (void) sc; } while (0)
#endif
#endif /* __IF_WPI_DEBUG_H__ */

View File

@ -1,4 +1,4 @@
/* $FreeBSD$ */
/* $FreeBSD: releng/11.1/sys/dev/wpi/if_wpivar.h 297173 2016-03-21 23:25:41Z avos $ */
/*-
* Copyright (c) 2006,2007
@ -16,8 +16,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <net80211/ieee80211_amrr.h>
struct wpi_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
uint64_t wr_tsft;
@ -28,7 +26,7 @@ struct wpi_rx_radiotap_header {
int8_t wr_dbm_antsignal;
int8_t wr_dbm_antnoise;
uint8_t wr_antenna;
};
} __packed;
#define WPI_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_TSFT) | \
@ -45,8 +43,7 @@ struct wpi_tx_radiotap_header {
uint8_t wt_rate;
uint16_t wt_chan_freq;
uint16_t wt_chan_flags;
uint8_t wt_hwqueue;
};
} __packed;
#define WPI_TX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
@ -55,16 +52,15 @@ struct wpi_tx_radiotap_header {
struct wpi_dma_info {
bus_dma_tag_t tag;
bus_dmamap_t map;
bus_addr_t paddr; /* aligned p address */
bus_addr_t paddr_start; /* possibly unaligned p start*/
caddr_t vaddr; /* aligned v address */
caddr_t vaddr_start; /* possibly unaligned v start */
bus_dmamap_t map;
bus_addr_t paddr;
caddr_t vaddr;
bus_size_t size;
};
struct wpi_tx_data {
bus_dmamap_t map;
bus_addr_t cmd_paddr;
struct mbuf *m;
struct ieee80211_node *ni;
};
@ -74,19 +70,18 @@ struct wpi_tx_ring {
struct wpi_dma_info cmd_dma;
struct wpi_tx_desc *desc;
struct wpi_tx_cmd *cmd;
struct wpi_tx_data *data;
struct wpi_tx_data data[WPI_TX_RING_COUNT];
bus_dma_tag_t data_dmat;
int qid;
int count;
int queued;
int cur;
uint8_t qid;
uint8_t cur;
uint8_t pending;
int16_t queued;
int update:1;
};
#define WPI_RBUF_COUNT ( WPI_RX_RING_COUNT + 16 )
struct wpi_rx_data {
bus_dmamap_t map;
struct mbuf *m;
struct mbuf *m;
bus_dmamap_t map;
};
struct wpi_rx_ring {
@ -94,17 +89,15 @@ struct wpi_rx_ring {
uint32_t *desc;
struct wpi_rx_data data[WPI_RX_RING_COUNT];
bus_dma_tag_t data_dmat;
int cur;
uint16_t cur;
int update;
};
struct wpi_amrr {
struct ieee80211_node ni; /* must be the first */
int txcnt;
int retrycnt;
int success;
int success_threshold;
int recovery;
struct wpi_node {
struct ieee80211_node ni; /* must be the first */
uint8_t id;
};
#define WPI_NODE(ni) ((struct wpi_node *)(ni))
struct wpi_power_sample {
uint8_t index;
@ -119,88 +112,186 @@ struct wpi_power_group {
int16_t temp;
};
struct wpi_vap {
struct ieee80211vap vap;
struct wpi_buf {
uint8_t data[56]; /* sizeof(struct wpi_cmd_beacon) */
struct ieee80211_node *ni;
struct mbuf *m;
size_t size;
uint8_t code;
uint16_t ac;
};
int (*newstate)(struct ieee80211vap *,
struct wpi_vap {
struct ieee80211vap wv_vap;
struct wpi_buf wv_bcbuf;
struct mtx wv_mtx;
uint8_t wv_gtk;
#define WPI_VAP_KEY(kid) (1 << kid)
int (*wv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
void (*wv_recv_mgmt)(struct ieee80211_node *,
struct mbuf *, int,
const struct ieee80211_rx_stats *,
int, int);
};
#define WPI_VAP(vap) ((struct wpi_vap *)(vap))
#define WPI_VAP_LOCK_INIT(_wvp) \
mtx_init(&(_wvp)->wv_mtx, "lock for wv_bcbuf/wv_boff structures", \
NULL, MTX_DEF)
#define WPI_VAP_LOCK(_wvp) mtx_lock(&(_wvp)->wv_mtx)
#define WPI_VAP_UNLOCK(_wvp) mtx_unlock(&(_wvp)->wv_mtx)
#define WPI_VAP_LOCK_ASSERT(_wvp) mtx_assert(&(_wvp)->wv_mtx, MA_OWNED)
#define WPI_VAP_LOCK_DESTROY(_wvp) mtx_destroy(&(_wvp)->wv_mtx)
struct wpi_fw_part {
const uint8_t *text;
uint32_t textsz;
const uint8_t *data;
uint32_t datasz;
};
struct wpi_fw_info {
const uint8_t *data;
size_t size;
struct wpi_fw_part init;
struct wpi_fw_part main;
struct wpi_fw_part boot;
};
struct wpi_softc {
device_t sc_dev;
struct ifnet *sc_ifp;
int sc_debug;
int sc_running;
struct mtx sc_mtx;
struct ieee80211com sc_ic;
/* Flags indicating the current state the driver
* expects the hardware to be in
*/
uint32_t flags;
#define WPI_FLAG_HW_RADIO_OFF (1 << 0)
#define WPI_FLAG_BUSY (1 << 1)
#define WPI_FLAG_AUTH (1 << 2)
struct mtx tx_mtx;
/* shared area */
/* Shared area. */
struct wpi_dma_info shared_dma;
struct wpi_shared *shared;
struct wpi_tx_ring txq[WME_NUM_AC];
struct wpi_tx_ring cmdq;
struct wpi_tx_ring txq[WPI_DRV_NTXQUEUES];
struct mtx txq_mtx;
struct mtx txq_state_mtx;
struct wpi_rx_ring rxq;
uint64_t rx_tstamp;
/* TX Thermal Callibration */
/* TX Thermal Callibration. */
struct callout calib_to;
int calib_cnt;
/* Watch dog timer */
struct callout watchdog_to;
/* Hardware switch polling timer */
struct callout hwswitch_to;
struct callout scan_timeout;
struct callout tx_timeout;
/* Watch dog timer. */
struct callout watchdog_rfkill;
/* Firmware image. */
struct wpi_fw_info fw;
uint32_t errptr;
struct resource *irq;
struct resource *mem;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
void *sc_ih;
bus_size_t sc_sz;
int sc_cap_off; /* PCIe Capabilities. */
struct wpi_rxon rxon;
struct mtx rxon_mtx;
struct wpi_config config;
int temp;
uint32_t nodesmsk;
struct mtx nt_mtx;
int sc_tx_timer;
int sc_scan_timer;
void (*sc_node_free)(struct ieee80211_node *);
void (*sc_update_rx_ring)(struct wpi_softc *);
void (*sc_update_tx_ring)(struct wpi_softc *,
struct wpi_tx_ring *);
struct bpf_if *sc_drvbpf;
struct wpi_rx_radiotap_header sc_rxtap;
struct wpi_tx_radiotap_header sc_txtap;
struct wpi_rx_radiotap_header sc_rxtap;
struct wpi_tx_radiotap_header sc_txtap;
/* firmware image */
/* Firmware image. */
const struct firmware *fw_fp;
/* firmware DMA transfer */
/* Firmware DMA transfer. */
struct wpi_dma_info fw_dma;
/* Tasks used by the driver */
struct task sc_restarttask; /* reset firmware task */
struct task sc_radiotask; /* reset rf task */
/* Tasks used by the driver. */
struct task sc_radiooff_task;
struct task sc_radioon_task;
/* Eeprom info */
/* Eeprom info. */
uint8_t cap;
uint16_t rev;
uint8_t type;
struct wpi_eeprom_chan
eeprom_channels[WPI_CHAN_BANDS_COUNT][WPI_MAX_CHAN_PER_BAND];
struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT];
int8_t maxpwr[IEEE80211_CHAN_MAX];
char domain[4]; /*reglatory domain XXX */
char domain[4]; /* Regulatory domain. */
#if defined(__HAIKU__)
uint32_t sc_intr_status;
uint32_t sc_intr_status_1;
uint32_t sc_intr_status_2;
#endif
};
/*
* Locking order:
* 1. WPI_LOCK;
* 2. WPI_RXON_LOCK;
* 3. WPI_TX_LOCK;
* 4. WPI_NT_LOCK / WPI_VAP_LOCK;
* 5. WPI_TXQ_LOCK;
* 6. WPI_TXQ_STATE_LOCK;
*/
#define WPI_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
MTX_NETWORK_LOCK, MTX_DEF)
MTX_NETWORK_LOCK, MTX_DEF)
#define WPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define WPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define WPI_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
#define WPI_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
#define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
#define WPI_RXON_LOCK_INIT(_sc) \
mtx_init(&(_sc)->rxon_mtx, "lock for wpi_rxon structure", NULL, MTX_DEF)
#define WPI_RXON_LOCK(_sc) mtx_lock(&(_sc)->rxon_mtx)
#define WPI_RXON_UNLOCK(_sc) mtx_unlock(&(_sc)->rxon_mtx)
#define WPI_RXON_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rxon_mtx, MA_OWNED)
#define WPI_RXON_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rxon_mtx)
#define WPI_TX_LOCK_INIT(_sc) \
mtx_init(&(_sc)->tx_mtx, "tx path lock", NULL, MTX_DEF)
#define WPI_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
#define WPI_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
#define WPI_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx)
#define WPI_NT_LOCK_INIT(_sc) \
mtx_init(&(_sc)->nt_mtx, "node table lock", NULL, MTX_DEF)
#define WPI_NT_LOCK(_sc) mtx_lock(&(_sc)->nt_mtx)
#define WPI_NT_UNLOCK(_sc) mtx_unlock(&(_sc)->nt_mtx)
#define WPI_NT_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->nt_mtx)
#define WPI_TXQ_LOCK_INIT(_sc) \
mtx_init(&(_sc)->txq_mtx, "txq/cmdq lock", NULL, MTX_DEF)
#define WPI_TXQ_LOCK(_sc) mtx_lock(&(_sc)->txq_mtx)
#define WPI_TXQ_UNLOCK(_sc) mtx_unlock(&(_sc)->txq_mtx)
#define WPI_TXQ_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->txq_mtx)
#define WPI_TXQ_STATE_LOCK_INIT(_sc) \
mtx_init(&(_sc)->txq_state_mtx, "txq state lock", NULL, MTX_DEF)
#define WPI_TXQ_STATE_LOCK(_sc) mtx_lock(&(_sc)->txq_state_mtx)
#define WPI_TXQ_STATE_UNLOCK(_sc) mtx_unlock(&(_sc)->txq_state_mtx)
#define WPI_TXQ_STATE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->txq_state_mtx)

View File

@ -1,6 +1,7 @@
/*
* Copyright 2009, Colin Günther, coling@gmx.de.
* All Rights Reserved. Distributed under the terms of the MIT License.
* Copyright 2018, Haiku, Inc.
* All rights reserved. Distributed under the terms of the MIT license.
*/
@ -30,15 +31,24 @@ int
HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
{
struct wpi_softc* sc = (struct wpi_softc*)device_get_softc(dev);
uint32 r;
uint32 r1, r2;
if ((r = WPI_READ(sc, WPI_INTR)) == 0 || r == 0xffffffff)
return 0;
r1 = WPI_READ(sc, WPI_INT);
atomic_set((int32*)&sc->sc_intr_status, r);
if (__predict_false(r1 == 0xffffffff ||
(r1 & 0xfffffff0) == 0xa5a5a5a0))
return 0; /* Hardware gone! */
WPI_WRITE(sc, WPI_MASK, 0);
// disable interrupts
r2 = WPI_READ(sc, WPI_FH_INT);
if (r1 == 0 && r2 == 0)
return 0; /* Interrupt not for us. */
/* Disable interrupts. */
WPI_WRITE(sc, WPI_INT_MASK, 0);
atomic_set((int32*)&sc->sc_intr_status_1, r1);
atomic_set((int32*)&sc->sc_intr_status_2, r2);
return 1;
}