Fix previous screwup.

This is the real bwi driver.
Ported by Taylor R. Campbell
This commit is contained in:
macallan 2009-01-09 20:49:42 +00:00
parent 2af193eec9
commit d6ded78b71
4 changed files with 1810 additions and 1386 deletions

File diff suppressed because it is too large Load Diff

@ -1,3 +1,4 @@
/* $NetBSD: bwireg.h,v 1.2 2009/01/09 20:49:42 macallan Exp $ */
/* $OpenBSD: bwireg.h,v 1.7 2007/11/17 16:50:02 mglocker Exp $ */
/*
@ -36,8 +37,8 @@
* $DragonFly: src/sys/dev/netif/bwi/if_bwireg.h,v 1.1 2007/09/08 06:15:54 sephe Exp $
*/
#ifndef _IF_BWIREG_H
#define _IF_BWIREG_H
#ifndef _DEV_IC_BWIREG_H
#define _DEV_IC_BWIREG_H
/*
* Registers for all of the register windows
@ -232,6 +233,8 @@
/* MAC address of pairwise keys */
#define BWI_PKEY_ADDR_MOBJ 0x4
/* [TRC: XXX Adapt DragonFlyBSD's more elaborate TX status flags, perhaps.
See bwi_txeof &c.] */
#define BWI_TXSTATUS_0 0x00000170
#define BWI_TXSTATUS_0_MORE (1 << 0)
#define BWI_TXSTATUS_0_TXID_MASK 0xffff0000
@ -334,7 +337,7 @@
/*
* Extended PCI registers
*/
#define BWI_PCIR_BAR PCIR_BAR(0)
#define BWI_PCIR_BAR 0x10 /* [TRC: Was PCIR_BAR(0).] */
#define BWI_PCIR_SEL_REGWIN 0x00000080
/* Register value for BWI_PCIR_SEL_REGWIN */
#define BWI_PCIM_REGWIN(id) (((id) * 0x1000) + 0x18000000)
@ -483,7 +486,7 @@
#define BWI_TXRX_TX_INTRS BWI_TXRX_INTR_ERROR
#define BWI_TXRX_RX_INTRS (BWI_TXRX_INTR_ERROR | BWI_TXRX_INTR_RX)
#define BWI_TXRX_IS_RX(i) ((i) % 3 == 0)
/* PHY */
#define BWI_PHYR_NRSSI_THR_11B 0x020
@ -633,7 +636,7 @@
0x3f22f46c, 0x3d96ee2b, 0x3b97e88e, 0x38d7e2b4, \
0x35c8dd9f, 0x325ad826, 0x2e03d358, 0x299acf64, \
0x246dcb87
/* RF */
#define BWI_RFR_ATTEN 0x43
@ -675,11 +678,4 @@
33, 28, 22, 14, 5, -7, -20, -20, \
-20, -20, -20, -20, -20, -20, -20, -20
/* Find least significant bit that is set */
#define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask))
#define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask))
#define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask))
#define __SHIFTOUT_MASK(__mask) __SHIFTOUT((__mask), (__mask))
#endif /* !_IF_BWIREG_H */
#endif /* !_DEV_IC_BWIREG_H */

@ -1,3 +1,4 @@
/* $NetBSD: bwivar.h,v 1.2 2009/01/09 20:49:42 macallan Exp $ */
/* $OpenBSD: bwivar.h,v 1.23 2008/02/25 20:36:54 mglocker Exp $ */
/*
@ -36,8 +37,8 @@
* $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.1 2007/09/08 06:15:54 sephe Exp $
*/
#ifndef _IF_BWIVAR_H
#define _IF_BWIVAR_H
#ifndef _DEV_IC_BWIVAR_H
#define _DEV_IC_BWIVAR_H
#define BWI_ALIGN 0x1000
#define BWI_RING_ALIGN BWI_ALIGN
@ -71,6 +72,11 @@ enum bwi_txpwrcb_type {
#define BWI_NOISE_FLOOR -95 /* TODO: noise floor calc */
/* [TRC: Bizarreness. Cf. bwi_rxeof in OpenBSD's if_bwi.c and
DragonFlyBSD's bwi.c.] */
#define BWI_FRAME_MIN_LEN(hdr) \
((hdr) + sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN)
#define CSR_READ_4(sc, reg) \
bus_space_read_4((sc)->sc_mem_bt, (sc)->sc_mem_bh, (reg))
#define CSR_READ_2(sc, reg) \
@ -262,10 +268,16 @@ struct bwi_fwhdr {
#define BWI_FW_IV_OFS_MASK 0x7fff
#define BWI_FW_IV_IS_32BIT (1 << 15)
struct fwheader {
char filename[64];
int filesize;
int fileoffset;
#define BWI_FW_NAME_FORMAT "v%d/%s%d.fw"
#define BWI_FW_UCODE_PREFIX "ucode"
#define BWI_FW_PCM_PREFIX "pcm"
#define BWI_FW_IV_PREFIX "b0g0initvals"
#define BWI_FW_IV_EXT_PREFIX "b0g0bsinitvals"
struct bwi_fw_image {
char fwi_name[64];
uint8_t *fwi_data;
size_t fwi_size;
};
struct bwi_fw_iv {
@ -431,18 +443,21 @@ struct bwi_mac {
struct bwi_tpctl mac_tpctl; /* TX power control */
uint32_t mac_flags; /* BWI_MAC_F_ */
uint8_t *mac_fw;
size_t mac_fw_size;
uint8_t *mac_ucode;
size_t mac_ucode_size;
uint8_t *mac_pcm;
size_t mac_pcm_size;
uint8_t *mac_iv;
size_t mac_iv_size;
uint8_t *mac_iv_ext;
size_t mac_iv_ext_size;
struct bwi_fw_image mac_ucode_fwi;
struct bwi_fw_image mac_pcm_fwi;
struct bwi_fw_image mac_iv_fwi;
struct bwi_fw_image mac_iv_ext_fwi;
};
#define mac_ucode mac_ucode_fwi.fwi_data
#define mac_ucode_size mac_ucode_fwi.fwi_size
#define mac_pcm mac_pcm_fwi.fwi_data
#define mac_pcm_size mac_pcm_fwi.fwi_size
#define mac_iv mac_iv_fwi.fwi_data
#define mac_iv_size mac_iv_fwi.fwi_size
#define mac_iv_ext mac_iv_ext_fwi.fwi_data
#define mac_iv_ext_size mac_iv_ext_fwi.fwi_size
#define BWI_MAC_F_BSWAP 0x1
#define BWI_MAC_F_TPCTL_INITED 0x2
#define BWI_MAC_F_HAS_TXSTATS 0x4
@ -501,6 +516,7 @@ struct bwi_rx_radiotap_hdr {
/* TODO: sq */
};
/* [TRC: XXX amrr] */
struct bwi_node {
struct ieee80211_node ni;
struct ieee80211_amrr_node amn;
@ -508,8 +524,11 @@ struct bwi_node {
struct bwi_softc {
struct device sc_dev;
struct ethercom sc_ec;
struct ieee80211com sc_ic;
#define sc_if sc_ec.ec_if
uint32_t sc_flags; /* BWI_F_ */
void *sc_ih; /* [TRC: interrupt handler] */
uint32_t sc_cap; /* BWI_CAP_ */
uint16_t sc_bbp_id; /* BWI_BBPID_ */
@ -525,20 +544,25 @@ struct bwi_softc {
uint16_t sc_pwron_delay;
int sc_locale;
/* [TRC: No clue what these are for.]
int sc_irq_rid;
struct resource *sc_irq_res;
void *sc_irq_handle;
*/
/* [TRC: Likewise.]
int sc_mem_rid;
struct resource *sc_mem_res;
*/
bus_dma_tag_t sc_dmat;
bus_space_tag_t sc_mem_bt;
bus_space_handle_t sc_mem_bh;
struct timeout sc_scan_ch;
struct timeout sc_calib_ch;
struct timeout sc_amrr_ch;
struct callout sc_scan_ch;
struct callout sc_calib_ch;
/* [TRC: XXX amrr] */
struct callout sc_amrr_ch;
struct ieee80211_amrr sc_amrr;
struct bwi_regwin *sc_cur_regwin;
@ -555,8 +579,7 @@ struct bwi_softc {
int sc_led_blinking;
int sc_led_ticks;
struct bwi_led *sc_blink_led;
struct timeout sc_led_blink_next_ch;
struct timeout sc_led_blink_end_ch;
struct callout sc_led_blink_ch;
int sc_led_blink_offdur;
struct bwi_led sc_leds[BWI_LED_MAX];
@ -603,34 +626,55 @@ struct bwi_softc {
void (*sc_conf_write)(void *, uint32_t, uint32_t);
uint32_t (*sc_conf_read)(void *, uint32_t);
struct sysctllog *sc_sysctllog;
/* Sysctl variables */
int sc_fw_version; /* BWI_FW_VERSION[34] */
int sc_dwell_time; /* milliseconds */
int sc_led_idle;
int sc_led_blink;
int sc_txpwr_calib;
int sc_debug; /* BWI_DBG_ */
#if NBPFILTER > 0
void *sc_drvbpf;
struct bpf_if *sc_drvbpf;
union {
struct bwi_rx_radiotap_hdr th;
uint8_t pad[64];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
int sc_rxtap_len;
union {
struct bwi_rx_radiotap_hdr th;
uint8_t pad[64];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
int sc_rxtap_len;
union {
struct bwi_tx_radiotap_hdr th;
uint8_t pad[64];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
int sc_txtap_len;
union {
struct bwi_tx_radiotap_hdr th;
uint8_t pad[64];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
int sc_txtap_len;
#endif
};
#define BWI_F_BUS_INITED 0x1
#define BWI_F_PROMISC 0x2
#define BWI_DBG_MAC 0x00000001
#define BWI_DBG_RF 0x00000002
#define BWI_DBG_PHY 0x00000004
#define BWI_DBG_MISC 0x00000008
#define BWI_DBG_ATTACH 0x00000010
#define BWI_DBG_INIT 0x00000020
#define BWI_DBG_FIRMWARE 0x00000040
#define BWI_DBG_80211 0x00000080
#define BWI_DBG_TXPOWER 0x00000100
#define BWI_DBG_INTR 0x00000200
#define BWI_DBG_RX 0x00000400
#define BWI_DBG_TX 0x00000800
#define BWI_DBG_TXEOF 0x00001000
#define BWI_DBG_LED 0x00002000
#define BWI_DBG_STATION 0x00004000
#define abs(a) __builtin_abs(a)
#define MOBJ_WRITE_2(mac, objid, ofs, val) \
@ -741,8 +785,10 @@ bwi_rf_lo_update(struct bwi_mac *_mac)
#define RF_FILT_SETBITS(mac, ofs, filt, bits) \
RF_WRITE((mac), (ofs), (RF_READ((mac), (ofs)) & (filt)) | (bits))
#endif /* !_IF_BWIVAR_H */
/* [TRC: XXX Why are these visible at all externally?] */
int bwi_intr(void *);
int bwi_attach(struct bwi_softc *);
int bwi_detach(void *);
void bwi_detach(struct bwi_softc *);
#endif /* !_DEV_IC_BWIVAR_H */

@ -1,4 +1,5 @@
/* $OpenBSD: if_bwi_pci.c,v 1.7 2008/05/23 08:49:27 brad Exp $ */
/* $NetBSD: if_bwi_pci.c,v 1.2 2009/01/09 20:49:42 macallan Exp $ */
/* $OpenBSD: if_bwi_pci.c,v 1.6 2008/02/14 22:10:02 brad Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@ -17,29 +18,32 @@
*/
/*
* PCI front-end for the Broadcom AirForce
* Broadcom AirForce BCM43xx IEEE 802.11b/g wireless network driver
* PCI front end
*/
#include "bpfilter.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_bwi_pci.c,v 1.2 2009/01/09 20:49:42 macallan Exp $");
#include <sys/param.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/callout.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_ether.h>
#include <net/if_media.h>
#include <netinet/in.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_radiotap.h>
@ -53,49 +57,51 @@
/* Base Address Register */
#define BWI_PCI_BAR0 0x10
int bwi_pci_match(struct device *, void *, void *);
void bwi_pci_attach(struct device *, struct device *, void *);
int bwi_pci_detach(struct device *, int);
void bwi_pci_conf_write(void *, uint32_t, uint32_t);
uint32_t bwi_pci_conf_read(void *, uint32_t);
static int bwi_pci_match(struct device *, struct cfdata *, void *);
static void bwi_pci_attach(struct device *, struct device *, void *);
static int bwi_pci_detach(struct device *, int);
static void bwi_pci_conf_write(void *, uint32_t, uint32_t);
static uint32_t bwi_pci_conf_read(void *, uint32_t);
struct bwi_pci_softc {
struct bwi_softc psc_bwi;
pci_chipset_tag_t psc_pc;
pcitag_t psc_pcitag;
void *psc_ih;
bus_size_t psc_mapsize;
};
struct cfattach bwi_pci_ca = {
sizeof(struct bwi_pci_softc), bwi_pci_match, bwi_pci_attach,
bwi_pci_detach
};
CFATTACH_DECL(bwi_pci, sizeof(struct bwi_pci_softc),
bwi_pci_match, bwi_pci_attach, bwi_pci_detach, NULL);
const struct pci_matchid bwi_pci_devices[] = {
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4303 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4306 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4306_2 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4307 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4309 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4311 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4312 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4318 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4319 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4322 },
{ PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM43XG }
};
int
bwi_pci_match(struct device *parent, void *match, void *aux)
static int
bwi_pci_match(struct device *parent, struct cfdata *match, void *aux)
{
return (pci_matchbyid((struct pci_attach_args *)aux, bwi_pci_devices,
sizeof(bwi_pci_devices) / sizeof(bwi_pci_devices[0])));
struct pci_attach_args *pa = aux;
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_BROADCOM)
return (0);
switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_BROADCOM_BCM4303:
case PCI_PRODUCT_BROADCOM_BCM4306:
case PCI_PRODUCT_BROADCOM_BCM4306_2:
case PCI_PRODUCT_BROADCOM_BCM4307:
case PCI_PRODUCT_BROADCOM_BCM4309:
case PCI_PRODUCT_BROADCOM_BCM4311:
case PCI_PRODUCT_BROADCOM_BCM4312:
case PCI_PRODUCT_BROADCOM_BCM4318:
case PCI_PRODUCT_BROADCOM_BCM4319:
case PCI_PRODUCT_BROADCOM_BCM4322:
case PCI_PRODUCT_BROADCOM_BCM43XG:
return (1);
}
return (0);
}
void
static void
bwi_pci_attach(struct device *parent, struct device *self, void *aux)
{
struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
@ -111,29 +117,37 @@ bwi_pci_attach(struct device *parent, struct device *self, void *aux)
/* map control / status registers */
memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BWI_PCI_BAR0);
if (pci_mapreg_map(pa, BWI_PCI_BAR0, memtype, 0, &sc->sc_mem_bt,
&sc->sc_mem_bh, NULL, &psc->psc_mapsize, 0)) {
printf(": could not map memory space\n");
switch (memtype) {
case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
if (pci_mapreg_map(pa, BWI_PCI_BAR0,
memtype, 0, &sc->sc_mem_bt, &sc->sc_mem_bh,
NULL, &psc->psc_mapsize) == 0)
break;
default:
aprint_error(": could not map memory space\n");
return;
}
aprint_normal("\n");
/* map interrupt */
if (pci_intr_map(pa, &ih) != 0) {
printf(": could not map interrupt\n");
aprint_error_dev(self, "could not map interrupt\n");
return;
}
/* establish interrupt */
intrstr = pci_intr_string(psc->psc_pc, ih);
psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc);
if (psc->psc_ih == NULL) {
printf(": could not establish interrupt");
sc->sc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc);
if (sc->sc_ih == NULL) {
aprint_error_dev(self, "could not establish interrupt");
if (intrstr != NULL)
printf(" at %s", intrstr);
printf("\n");
aprint_error(" at %s", intrstr);
aprint_error("\n");
return;
}
printf(": %s", intrstr);
aprint_normal_dev(self, "interrupting at %s\n", intrstr);
/* we need to access PCI config space from the driver */
sc->sc_conf_write = bwi_pci_conf_write;
@ -156,12 +170,16 @@ bwi_pci_detach(struct device *self, int flags)
struct bwi_softc *sc = &psc->psc_bwi;
bwi_detach(sc);
pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
if (sc->sc_ih != NULL) {
pci_intr_disestablish(psc->psc_pc, sc->sc_ih);
sc->sc_ih = NULL;
}
return (0);
}
void
static void
bwi_pci_conf_write(void *self, uint32_t reg, uint32_t val)
{
struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
@ -169,7 +187,7 @@ bwi_pci_conf_write(void *self, uint32_t reg, uint32_t val)
pci_conf_write(psc->psc_pc, psc->psc_pcitag, reg, val);
}
uint32_t
static uint32_t
bwi_pci_conf_read(void *self, uint32_t reg)
{
struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;