Update wpi(4) with stability fixes

- remove second taskqueue
 - busdma 16k alignment workaround
 - use busdma instead of external mbuf storage on Rx
 - locking fixes
 - net80211 state change fixes
 - improve scanning reliability
 - improve radio hw switch interaction
 - consolidate callouts

Parts obtained from:	benjsc, sam
Tested by:		many
This commit is contained in:
Andrew Thompson 2008-03-10 23:16:48 +00:00
parent c143ac21af
commit 82f1b132a4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=177043
3 changed files with 528 additions and 621 deletions

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,7 @@
#define WPI_GPIO_CTL 0x024
#define WPI_EEPROM_CTL 0x02c
#define WPI_EEPROM_STATUS 0x030
#define WPI_UCODE_SET 0x058
#define WPI_UCODE_CLR 0x05c
#define WPI_TEMPERATURE 0x060
#define WPI_CHICKEN 0x100
@ -201,6 +202,7 @@ struct wpi_rx_desc {
#define WPI_RX_DONE 27
#define WPI_TX_DONE 28
#define WPI_START_SCAN 130
#define WPI_SCAN_RESULTS 131
#define WPI_STOP_SCAN 132
#define WPI_STATE_CHANGED 161
#define WPI_MISSED_BEACON 162

View file

@ -16,17 +16,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if ( __FreeBSD_version > 700000 )
#include <net80211/ieee80211_amrr.h>
#else
#include <dev/wpi/ieee80211_amrr.h>
#endif
/* DMA mapping */
struct wpi_mapping {
int nsegs;
bus_dma_segment_t segs[WPI_MAX_SCATTER];
};
struct wpi_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
@ -66,8 +56,10 @@ struct wpi_tx_radiotap_header {
struct wpi_dma_info {
bus_dma_tag_t tag;
bus_dmamap_t map;
bus_addr_t paddr;
caddr_t vaddr;
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_size_t size;
};
@ -92,26 +84,16 @@ struct wpi_tx_ring {
#define WPI_RBUF_COUNT ( WPI_RX_RING_COUNT + 16 )
struct wpi_softc;
struct wpi_rbuf {
struct wpi_softc *sc;
bus_addr_t paddr;
caddr_t vaddr;
SLIST_ENTRY(wpi_rbuf) next;
};
struct wpi_rx_data {
struct mbuf *m;
bus_dmamap_t map;
struct mbuf *m;
};
struct wpi_rx_ring {
struct wpi_dma_info desc_dma;
struct wpi_dma_info buf_dma;
uint32_t *desc;
struct wpi_rx_data data[WPI_RX_RING_COUNT];
struct wpi_rbuf rbuf[WPI_RBUF_COUNT];
SLIST_HEAD(, wpi_rbuf) freelist;
bus_dma_tag_t data_dmat;
int cur;
};
@ -165,10 +147,6 @@ struct wpi_softc {
#define WPI_FLAG_BUSY (1 << 2)
#define WPI_FLAG_AUTH (1 << 3)
/* Flags indicating the state of the firmware */
uint32_t fw_state;
#define WPI_FW_IDLE (1 << 0 )
/* shared area */
struct wpi_dma_info shared_dma;
struct wpi_shared *shared;
@ -183,7 +161,8 @@ struct wpi_softc {
/* Watch dog timer */
struct callout watchdog_to;
int watchdog_cnt;
/* Hardware switch polling timer */
struct callout hwswitch_to;
struct resource *irq;
struct resource *mem;
@ -198,6 +177,7 @@ struct wpi_softc {
int sc_tx_timer;
int sc_scan_timer;
struct bpf_if *sc_drvbpf;
@ -213,14 +193,21 @@ struct wpi_softc {
struct wpi_dma_info fw_dma;
/* command queue related variables */
#define WPI_CMD_MAXOPS 10
#define WPI_SCAN_START (1<<0)
#define WPI_SCAN_CURCHAN (1<<1)
#define WPI_SCAN_STOP (1<<2)
#define WPI_SET_CHAN (1<<3)
#define WPI_AUTH (1<<4)
#define WPI_SCAN_NEXT (1<<5)
#define WPI_SCAN_START (1<<0)
#define WPI_SCAN_CURCHAN (1<<1)
#define WPI_SCAN_STOP (1<<2)
#define WPI_SET_CHAN (1<<3)
#define WPI_AUTH (1<<4)
#define WPI_RUN (1<<5)
#define WPI_SCAN_NEXT (1<<6)
#define WPI_RESTART (1<<7)
#define WPI_RF_RESTART (1<<8)
#define WPI_CMD_MAXOPS 10
/* command queuing request type */
#define WPI_QUEUE_NORMAL 0
#define WPI_QUEUE_CLEAR 1
int sc_cmd[WPI_CMD_MAXOPS];
int sc_cmd_arg[WPI_CMD_MAXOPS];
int sc_cmd_cur; /* current queued scan task */
int sc_cmd_next; /* last queued scan task */
struct mtx sc_cmdlock;
@ -246,24 +233,15 @@ struct wpi_softc {
#define WPI_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
MTX_NETWORK_LOCK, MTX_DEF)
#define WPI_LOCK_DECL int __waslocked = 0
#define WPI_LOCK(_sc) do {\
if (!(__waslocked = mtx_owned(&(_sc)->sc_mtx))) \
mtx_lock(&(_sc)->sc_mtx); \
} while(0)
#define WPI_UNLOCK(_sc) do { \
if (!__waslocked) \
mtx_unlock(&(_sc)->sc_mtx); \
} while (0)
#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_OWNED(_sc) mtx_owned(&(_sc)->sc_mtx)
#define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
#define WPI_CMD_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_cmdlock, device_get_nameunit((_sc)->sc_dev), NULL, MTX_DEF);
mtx_init(&(_sc)->sc_cmdlock, device_get_nameunit((_sc)->sc_dev), \
NULL, MTX_DEF)
#define WPI_CMD_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_cmdlock)
#define WPI_CMD_LOCK(_sc) mtx_lock(&(_sc)->sc_cmdlock)
#define WPI_CMD_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_cmdlock)
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
#define WPI_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
#else
#define WPI_LOCK_ASSERT(sc)
#endif