iprowifi2100: Sync with FreeBSD 11.1.

Untested, but mostly just changes to adapt to the new net80211 stack.
This commit is contained in:
Augustin Cavalier
2018-07-14 14:08:25 -04:00
parent 71bcccaeee
commit 1a9f01e8ed
6 changed files with 176 additions and 229 deletions
@@ -1,7 +1,6 @@
SubDir HAIKU_TOP src add-ons kernel drivers network wlan ; SubDir HAIKU_TOP src add-ons kernel drivers network wlan ;
# FreeBSD 9.2 drivers # FreeBSD 9.2 drivers
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ;
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan marvell88w8335 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan marvell88w8335 ;
# FreeBSD 9.3 drivers # FreeBSD 9.3 drivers
@@ -13,6 +12,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network wlan wavelanwifi ;
# FreeBSD 11.1 drivers # FreeBSD 11.1 drivers
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan aironetwifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan aironetwifi ;
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan atheroswifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan atheroswifi ;
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ;
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi3945 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi3945 ;
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi4965 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi4965 ;
@@ -1,14 +1,14 @@
SubDir HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ; SubDir HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ]
: true ; : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_wlan ] : true ;
UsePrivateHeaders net system ; UsePrivateHeaders net system ;
UsePrivateKernelHeaders ; UsePrivateKernelHeaders ;
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
-Wno-format -Wno-format
-Wno-unused -Wno-unused
-Wno-uninitialized ; -Wno-uninitialized ;
UseHeaders [ FDirName $(SUBDIR) ] : true ; UseHeaders [ FDirName $(SUBDIR) ] : true ;
@@ -19,8 +19,8 @@ KernelAddon iprowifi2100 :
if_ipw.c if_ipw.c
glue.c glue.c
: :
libfreebsd_wlan.a libfreebsd11_wlan.a
libfreebsd_network.a libfreebsd11_network.a
; ;
# Note: Due to licensing restrictions, we can only distribute the archive. # Note: Due to licensing restrictions, we can only distribute the archive.
@@ -1,5 +1,3 @@
/* $FreeBSD$ */
/*- /*-
* Copyright (c) 2004-2006 * Copyright (c) 2004-2006
* Damien Bergamini <[email protected]>. All rights reserved. * Damien Bergamini <[email protected]>. All rights reserved.
@@ -30,7 +28,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD: releng/11.1/sys/dev/ipw/if_ipw.c 300239 2016-05-19 22:19:35Z avos $");
/*- /*-
* Intel(R) PRO/Wireless 2100 MiniPCI driver * Intel(R) PRO/Wireless 2100 MiniPCI driver
@@ -62,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
#include <net/if_var.h>
#include <net/if_arp.h> #include <net/if_arp.h>
#include <net/ethernet.h> #include <net/ethernet.h>
#include <net/if_dl.h> #include <net/if_dl.h>
@@ -117,6 +116,7 @@ static void ipw_release(struct ipw_softc *);
static void ipw_media_status(struct ifnet *, struct ifmediareq *); static void ipw_media_status(struct ifnet *, struct ifmediareq *);
static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t); static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t);
static uint16_t ipw_read_chanmask(struct ipw_softc *);
static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *); static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *);
static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *);
static void ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *, static void ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *,
@@ -128,14 +128,14 @@ static void ipw_intr(void *);
static void ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int); static void ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int);
static const char * ipw_cmdname(int); static const char * ipw_cmdname(int);
static int ipw_cmd(struct ipw_softc *, uint32_t, void *, uint32_t); static int ipw_cmd(struct ipw_softc *, uint32_t, void *, uint32_t);
static int ipw_tx_start(struct ifnet *, struct mbuf *, static int ipw_tx_start(struct ipw_softc *, struct mbuf *,
struct ieee80211_node *); struct ieee80211_node *);
static int ipw_raw_xmit(struct ieee80211_node *, struct mbuf *, static int ipw_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *); const struct ieee80211_bpf_params *);
static void ipw_start(struct ifnet *); static int ipw_transmit(struct ieee80211com *, struct mbuf *);
static void ipw_start_locked(struct ifnet *); static void ipw_start(struct ipw_softc *);
static void ipw_watchdog(void *); static void ipw_watchdog(void *);
static int ipw_ioctl(struct ifnet *, u_long, caddr_t); static void ipw_parent(struct ieee80211com *);
static void ipw_stop_master(struct ipw_softc *); static void ipw_stop_master(struct ipw_softc *);
static int ipw_enable(struct ipw_softc *); static int ipw_enable(struct ipw_softc *);
static int ipw_disable(struct ipw_softc *); static int ipw_disable(struct ipw_softc *);
@@ -165,6 +165,8 @@ static void ipw_write_mem_1(struct ipw_softc *, bus_size_t,
static int ipw_scan(struct ipw_softc *); static int ipw_scan(struct ipw_softc *);
static void ipw_scan_start(struct ieee80211com *); static void ipw_scan_start(struct ieee80211com *);
static void ipw_scan_end(struct ieee80211com *); static void ipw_scan_end(struct ieee80211com *);
static void ipw_getradiocaps(struct ieee80211com *, int, int *,
struct ieee80211_channel[]);
static void ipw_set_channel(struct ieee80211com *); static void ipw_set_channel(struct ieee80211com *);
static void ipw_scan_curchan(struct ieee80211_scan_state *, static void ipw_scan_curchan(struct ieee80211_scan_state *,
unsigned long maxdwell); unsigned long maxdwell);
@@ -186,7 +188,7 @@ static device_method_t ipw_methods[] = {
DEVMETHOD(device_suspend, ipw_suspend), DEVMETHOD(device_suspend, ipw_suspend),
DEVMETHOD(device_resume, ipw_resume), DEVMETHOD(device_resume, ipw_resume),
{ 0, 0 } DEVMETHOD_END
}; };
static driver_t ipw_driver = { static driver_t ipw_driver = {
@@ -197,7 +199,7 @@ static driver_t ipw_driver = {
static devclass_t ipw_devclass; static devclass_t ipw_devclass;
DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, 0, 0); DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, NULL, NULL);
MODULE_VERSION(ipw, 1); MODULE_VERSION(ipw, 1);
@@ -210,48 +212,36 @@ ipw_probe(device_t dev)
if (pci_get_vendor(dev) == ident->vendor && if (pci_get_vendor(dev) == ident->vendor &&
pci_get_device(dev) == ident->device) { pci_get_device(dev) == ident->device) {
device_set_desc(dev, ident->name); device_set_desc(dev, ident->name);
return 0; return (BUS_PROBE_DEFAULT);
} }
} }
return ENXIO; return ENXIO;
} }
/* Base Address Register */ /* Base Address Register */
#define IPW_PCI_BAR0 0x10
static int static int
ipw_attach(device_t dev) ipw_attach(device_t dev)
{ {
struct ipw_softc *sc = device_get_softc(dev); struct ipw_softc *sc = device_get_softc(dev);
struct ifnet *ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic;
struct ieee80211_channel *c;
uint16_t val; uint16_t val;
int error, i; int error, i;
uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev; sc->sc_dev = dev;
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE); MTX_DEF | MTX_RECURSE);
mbufq_init(&sc->sc_snd, ifqmaxlen);
TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc); TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc);
callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
device_printf(dev, "chip is in D%d power mode "
"-- setting to D0\n", pci_get_powerstate(dev));
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
}
pci_write_config(dev, 0x41, 0, 1); pci_write_config(dev, 0x41, 0, 1);
/* enable bus-mastering */ /* enable bus-mastering */
pci_enable_busmaster(dev); pci_enable_busmaster(dev);
sc->mem_rid = IPW_PCI_BAR0; i = PCIR_BAR(0);
sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE);
RF_ACTIVE);
if (sc->mem == NULL) { if (sc->mem == NULL) {
device_printf(dev, "could not allocate memory resource\n"); device_printf(dev, "could not allocate memory resource\n");
goto fail; goto fail;
@@ -260,8 +250,8 @@ ipw_attach(device_t dev)
sc->sc_st = rman_get_bustag(sc->mem); sc->sc_st = rman_get_bustag(sc->mem);
sc->sc_sh = rman_get_bushandle(sc->mem); sc->sc_sh = rman_get_bushandle(sc->mem);
sc->irq_rid = 0; i = 0;
sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
RF_ACTIVE | RF_SHAREABLE); RF_ACTIVE | RF_SHAREABLE);
if (sc->irq == NULL) { if (sc->irq == NULL) {
device_printf(dev, "could not allocate interrupt resource\n"); device_printf(dev, "could not allocate interrupt resource\n");
@@ -278,24 +268,8 @@ ipw_attach(device_t dev)
goto fail2; goto fail2;
} }
ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); ic->ic_softc = sc;
if (ifp == NULL) { ic->ic_name = device_get_nameunit(dev);
device_printf(dev, "can not if_alloc()\n");
goto fail3;
}
ic = ifp->if_l2com;
ifp->if_softc = sc;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_init = ipw_init;
ifp->if_ioctl = ipw_ioctl;
ifp->if_start = ipw_start;
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
ic->ic_opmode = IEEE80211_M_STA; ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_DS; ic->ic_phytype = IEEE80211_T_DS;
@@ -311,42 +285,35 @@ ipw_attach(device_t dev)
/* read MAC address from EEPROM */ /* read MAC address from EEPROM */
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0); val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0);
macaddr[0] = val >> 8; ic->ic_macaddr[0] = val >> 8;
macaddr[1] = val & 0xff; ic->ic_macaddr[1] = val & 0xff;
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 1); val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 1);
macaddr[2] = val >> 8; ic->ic_macaddr[2] = val >> 8;
macaddr[3] = val & 0xff; ic->ic_macaddr[3] = val & 0xff;
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 2); val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 2);
macaddr[4] = val >> 8; ic->ic_macaddr[4] = val >> 8;
macaddr[5] = val & 0xff; ic->ic_macaddr[5] = val & 0xff;
/* set supported .11b channels (read from EEPROM) */ sc->chanmask = ipw_read_chanmask(sc);
if ((val = ipw_read_prom_word(sc, IPW_EEPROM_CHANNEL_LIST)) == 0) ipw_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
val = 0x7ff; /* default to channels 1-11 */ ic->ic_channels);
val <<= 1;
for (i = 1; i < 16; i++) {
if (val & (1 << i)) {
c = &ic->ic_channels[ic->ic_nchans++];
c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
c->ic_flags = IEEE80211_CHAN_B;
c->ic_ieee = i;
}
}
/* check support for radio transmitter switch in EEPROM */ /* check support for radio transmitter switch in EEPROM */
if (!(ipw_read_prom_word(sc, IPW_EEPROM_RADIO) & 8)) if (!(ipw_read_prom_word(sc, IPW_EEPROM_RADIO) & 8))
sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH; sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH;
ieee80211_ifattach(ic, macaddr); ieee80211_ifattach(ic);
ic->ic_scan_start = ipw_scan_start; ic->ic_scan_start = ipw_scan_start;
ic->ic_scan_end = ipw_scan_end; ic->ic_scan_end = ipw_scan_end;
ic->ic_getradiocaps = ipw_getradiocaps;
ic->ic_set_channel = ipw_set_channel; ic->ic_set_channel = ipw_set_channel;
ic->ic_scan_curchan = ipw_scan_curchan; ic->ic_scan_curchan = ipw_scan_curchan;
ic->ic_scan_mindwell = ipw_scan_mindwell; ic->ic_scan_mindwell = ipw_scan_mindwell;
ic->ic_raw_xmit = ipw_raw_xmit; ic->ic_raw_xmit = ipw_raw_xmit;
ic->ic_vap_create = ipw_vap_create; ic->ic_vap_create = ipw_vap_create;
ic->ic_vap_delete = ipw_vap_delete; ic->ic_vap_delete = ipw_vap_delete;
ic->ic_transmit = ipw_transmit;
ic->ic_parent = ipw_parent;
ieee80211_radiotap_attach(ic, ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -374,21 +341,20 @@ ipw_attach(device_t dev)
NULL, ipw_intr, sc, &sc->sc_ih); NULL, ipw_intr, sc, &sc->sc_ih);
if (error != 0) { if (error != 0) {
device_printf(dev, "could not set up interrupt\n"); device_printf(dev, "could not set up interrupt\n");
goto fail4; goto fail3;
} }
if (bootverbose) if (bootverbose)
ieee80211_announce(ic); ieee80211_announce(ic);
return 0; return 0;
fail4:
if_free(ifp);
fail3: fail3:
ipw_release(sc); ipw_release(sc);
fail2: fail2:
bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq), sc->irq);
fail1: fail1:
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem),
sc->mem);
fail: fail:
mtx_destroy(&sc->sc_mtx); mtx_destroy(&sc->sc_mtx);
return ENXIO; return ENXIO;
@@ -398,8 +364,9 @@ static int
ipw_detach(device_t dev) ipw_detach(device_t dev)
{ {
struct ipw_softc *sc = device_get_softc(dev); struct ipw_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
ieee80211_draintask(ic, &sc->sc_init_task); ieee80211_draintask(ic, &sc->sc_init_task);
ipw_stop(sc); ipw_stop(sc);
@@ -407,15 +374,14 @@ ipw_detach(device_t dev)
ieee80211_ifdetach(ic); ieee80211_ifdetach(ic);
callout_drain(&sc->sc_wdtimer); callout_drain(&sc->sc_wdtimer);
mbufq_drain(&sc->sc_snd);
ipw_release(sc); ipw_release(sc);
bus_teardown_intr(dev, sc->irq, sc->sc_ih); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq), sc->irq);
bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem),
sc->mem);
if_free(ifp);
if (sc->sc_firmware != NULL) { if (sc->sc_firmware != NULL) {
firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD);
@@ -433,8 +399,7 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN]) const uint8_t mac[IEEE80211_ADDR_LEN])
{ {
struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ic->ic_softc;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_vap *ivp; struct ipw_vap *ivp;
struct ieee80211vap *vap; struct ieee80211vap *vap;
const struct firmware *fp; const struct firmware *fp;
@@ -492,19 +457,17 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return NULL; return NULL;
} }
ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap), ivp = malloc(sizeof(struct ipw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
M_80211_VAP, M_NOWAIT | M_ZERO);
if (ivp == NULL)
return NULL;
vap = &ivp->vap; vap = &ivp->vap;
ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override with driver methods */ /* override with driver methods */
ivp->newstate = vap->iv_newstate; ivp->newstate = vap->iv_newstate;
vap->iv_newstate = ipw_newstate; vap->iv_newstate = ipw_newstate;
/* complete setup */ /* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status); ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status,
mac);
ic->ic_opmode = opmode; ic->ic_opmode = opmode;
return vap; return vap;
} }
@@ -758,11 +721,8 @@ ipw_release(struct ipw_softc *sc)
} }
if (sc->tbd_dmat != NULL) { if (sc->tbd_dmat != NULL) {
if (sc->stbd_list != NULL) { bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map);
bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map); bus_dmamem_free(sc->tbd_dmat, sc->tbd_list, sc->tbd_map);
bus_dmamem_free(sc->tbd_dmat, sc->tbd_list,
sc->tbd_map);
}
bus_dma_tag_destroy(sc->tbd_dmat); bus_dma_tag_destroy(sc->tbd_dmat);
} }
@@ -835,7 +795,7 @@ static int
ipw_suspend(device_t dev) ipw_suspend(device_t dev)
{ {
struct ipw_softc *sc = device_get_softc(dev); struct ipw_softc *sc = device_get_softc(dev);
struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211com *ic = &sc->sc_ic;
ieee80211_suspend_all(ic); ieee80211_suspend_all(ic);
return 0; return 0;
@@ -845,7 +805,7 @@ static int
ipw_resume(device_t dev) ipw_resume(device_t dev)
{ {
struct ipw_softc *sc = device_get_softc(dev); struct ipw_softc *sc = device_get_softc(dev);
struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211com *ic = &sc->sc_ic;
pci_write_config(dev, 0x41, 0, 1); pci_write_config(dev, 0x41, 0, 1);
@@ -874,7 +834,7 @@ ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{ {
struct ieee80211vap *vap = ifp->if_softc; struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic; struct ieee80211com *ic = vap->iv_ic;
struct ipw_softc *sc = ic->ic_ifp->if_softc; struct ipw_softc *sc = ic->ic_softc;
/* read current transmission rate from adapter */ /* read current transmission rate from adapter */
vap->iv_bss->ni_txrate = ipw_cvtrate( vap->iv_bss->ni_txrate = ipw_cvtrate(
@@ -887,8 +847,7 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{ {
struct ipw_vap *ivp = IPW_VAP(vap); struct ipw_vap *ivp = IPW_VAP(vap);
struct ieee80211com *ic = vap->iv_ic; struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ic->ic_softc;
struct ipw_softc *sc = ifp->if_softc;
enum ieee80211_state ostate; enum ieee80211_state ostate;
DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
@@ -1001,6 +960,19 @@ ipw_read_prom_word(struct ipw_softc *sc, uint8_t addr)
return le16toh(val); return le16toh(val);
} }
static uint16_t
ipw_read_chanmask(struct ipw_softc *sc)
{
uint16_t val;
/* set supported .11b channels (read from EEPROM) */
if ((val = ipw_read_prom_word(sc, IPW_EEPROM_CHANNEL_LIST)) == 0)
val = 0x7ff; /* default to channels 1-11 */
val <<= 1;
return (val);
}
static void static void
ipw_rx_cmd_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) ipw_rx_cmd_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
{ {
@@ -1023,8 +995,7 @@ static void
ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
{ {
#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state] #define IEEESTATE(vap) ieee80211_state_name[vap->iv_state]
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t state; uint32_t state;
@@ -1126,8 +1097,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
static void static void
ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
ic->ic_curchan = chan; ic->ic_curchan = chan;
ieee80211_radiotap_chan_change(ic); ieee80211_radiotap_chan_change(ic);
@@ -1140,8 +1110,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
static void static void
ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m) ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211_channel *c; struct ieee80211_channel *c;
struct ieee80211_frame *wh; struct ieee80211_frame *wh;
uint8_t subtype; uint8_t subtype;
@@ -1186,8 +1155,7 @@ static void
ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf) struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct mbuf *mnew, *m; struct mbuf *mnew, *m;
struct ieee80211_node *ni; struct ieee80211_node *ni;
bus_addr_t physaddr; bus_addr_t physaddr;
@@ -1209,7 +1177,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
*/ */
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) { if (mnew == NULL) {
ifp->if_ierrors++; counter_u64_add(ic->ic_ierrors, 1);
return; return;
} }
@@ -1230,7 +1198,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
panic("%s: could not load old rx mbuf", panic("%s: could not load old rx mbuf",
device_get_name(sc->sc_dev)); device_get_name(sc->sc_dev));
} }
ifp->if_ierrors++; counter_u64_add(ic->ic_ierrors, 1);
return; return;
} }
@@ -1241,9 +1209,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
m = sbuf->m; m = sbuf->m;
sbuf->m = mnew; sbuf->m = mnew;
sbd->bd->physaddr = htole32(physaddr); sbd->bd->physaddr = htole32(physaddr);
/* finalize mbuf */
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = le32toh(status->len); m->m_pkthdr.len = m->m_len = le32toh(status->len);
rssi = status->rssi + IPW_RSSI_TO_DBM; rssi = status->rssi + IPW_RSSI_TO_DBM;
@@ -1372,7 +1337,6 @@ ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd)
static void static void
ipw_tx_intr(struct ipw_softc *sc) ipw_tx_intr(struct ipw_softc *sc)
{ {
struct ifnet *ifp = sc->sc_ifp;
struct ipw_soft_bd *sbd; struct ipw_soft_bd *sbd;
uint32_t r, i; uint32_t r, i;
@@ -1383,10 +1347,6 @@ ipw_tx_intr(struct ipw_softc *sc)
for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD) { for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD) {
sbd = &sc->stbd_list[i]; sbd = &sc->stbd_list[i];
if (sbd->type == IPW_SBD_TYPE_DATA)
ifp->if_opackets++;
ipw_release_sbd(sc, sbd); ipw_release_sbd(sc, sbd);
sc->txfree++; sc->txfree++;
} }
@@ -1394,15 +1354,13 @@ ipw_tx_intr(struct ipw_softc *sc)
/* remember what the firmware has processed */ /* remember what the firmware has processed */
sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1; sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ipw_start(sc);
ipw_start_locked(ifp);
} }
static void static void
ipw_fatal_error_intr(struct ipw_softc *sc) ipw_fatal_error_intr(struct ipw_softc *sc)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
device_printf(sc->sc_dev, "firmware error\n"); device_printf(sc->sc_dev, "firmware error\n");
@@ -1470,7 +1428,6 @@ ipw_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
static const char * static const char *
ipw_cmdname(int cmd) ipw_cmdname(int cmd)
{ {
#define N(a) (sizeof(a) / sizeof(a[0]))
static const struct { static const struct {
int cmd; int cmd;
const char *name; const char *name;
@@ -1507,12 +1464,11 @@ ipw_cmdname(int cmd)
static char buf[12]; static char buf[12];
int i; int i;
for (i = 0; i < N(cmds); i++) for (i = 0; i < nitems(cmds); i++)
if (cmds[i].cmd == cmd) if (cmds[i].cmd == cmd)
return cmds[i].name; return cmds[i].name;
snprintf(buf, sizeof(buf), "%u", cmd); snprintf(buf, sizeof(buf), "%u", cmd);
return buf; return buf;
#undef N
} }
/* /*
@@ -1566,14 +1522,9 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len)
0, 0, len); 0, 0, len);
/* Print the data buffer in the higher debug level */ /* Print the data buffer in the higher debug level */
if (ipw_debug >= 9 && len > 0) { if (ipw_debug >= 9 && len > 0) {
#ifdef __HAIKU__
int i; int i;
printf(" data: 0x"); printf(" data: 0x");
for (i = 1; i <= len; i++) for (i = 1; i <= len; i++)
#else
printf(" data: 0x");
for (int i = 1; i <= len; i++)
#endif
printf("%1D", (u_char *)data + len - i, ""); printf("%1D", (u_char *)data + len - i, "");
} }
printf("\n"); printf("\n");
@@ -1597,10 +1548,9 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len)
} }
static int static int
ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) ipw_tx_start(struct ipw_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{ {
struct ipw_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = ni->ni_vap; struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh; struct ieee80211_frame *wh;
struct ipw_soft_bd *sbd; struct ipw_soft_bd *sbd;
@@ -1614,7 +1564,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
wh = mtod(m0, struct ieee80211_frame *); wh = mtod(m0, struct ieee80211_frame *);
if (wh->i_fc[1] & IEEE80211_FC1_WEP) { if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m0); k = ieee80211_crypto_encap(ni, m0);
if (k == NULL) { if (k == NULL) {
m_freem(m0); m_freem(m0);
@@ -1638,7 +1588,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
shdr->hdr.type = htole32(IPW_HDR_TYPE_SEND); shdr->hdr.type = htole32(IPW_HDR_TYPE_SEND);
shdr->hdr.subtype = 0; shdr->hdr.subtype = 0;
shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_WEP) ? 1 : 0; shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) ? 1 : 0;
shdr->hdr.encrypt = 0; shdr->hdr.encrypt = 0;
shdr->hdr.keyidx = 0; shdr->hdr.keyidx = 0;
shdr->hdr.keysz = 0; shdr->hdr.keysz = 0;
@@ -1754,38 +1704,42 @@ ipw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0; return 0;
} }
static void static int
ipw_start(struct ifnet *ifp) ipw_transmit(struct ieee80211com *ic, struct mbuf *m)
{ {
struct ipw_softc *sc = ifp->if_softc; struct ipw_softc *sc = ic->ic_softc;
int error;
IPW_LOCK(sc); IPW_LOCK(sc);
ipw_start_locked(ifp); if ((sc->flags & IPW_FLAG_RUNNING) == 0) {
IPW_UNLOCK(sc);
return (ENXIO);
}
error = mbufq_enqueue(&sc->sc_snd, m);
if (error) {
IPW_UNLOCK(sc);
return (error);
}
ipw_start(sc);
IPW_UNLOCK(sc); IPW_UNLOCK(sc);
return (0);
} }
static void static void
ipw_start_locked(struct ifnet *ifp) ipw_start(struct ipw_softc *sc)
{ {
struct ipw_softc *sc = ifp->if_softc;
struct ieee80211_node *ni; struct ieee80211_node *ni;
struct mbuf *m; struct mbuf *m;
IPW_LOCK_ASSERT(sc); IPW_LOCK_ASSERT(sc);
for (;;) { while (sc->txfree < 1 + IPW_MAX_NSEG &&
IFQ_DRV_DEQUEUE(&ifp->if_snd, m); (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
if (m == NULL)
break;
if (sc->txfree < 1 + IPW_MAX_NSEG) {
IFQ_DRV_PREPEND(&ifp->if_snd, m);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (ipw_tx_start(ifp, m, ni) != 0) { if (ipw_tx_start(sc, m, ni) != 0) {
if_inc_counter(ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni); ieee80211_free_node(ni);
ifp->if_oerrors++;
break; break;
} }
/* start watchdog timer */ /* start watchdog timer */
@@ -1797,15 +1751,14 @@ static void
ipw_watchdog(void *arg) ipw_watchdog(void *arg)
{ {
struct ipw_softc *sc = arg; struct ipw_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
IPW_LOCK_ASSERT(sc); IPW_LOCK_ASSERT(sc);
if (sc->sc_tx_timer > 0) { if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) { if (--sc->sc_tx_timer == 0) {
if_printf(ifp, "device timeout\n"); device_printf(sc->sc_dev, "device timeout\n");
ifp->if_oerrors++; counter_u64_add(ic->ic_oerrors, 1);
taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task); taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task);
} }
} }
@@ -1821,45 +1774,27 @@ ipw_watchdog(void *arg)
} }
} }
} }
if (ifp->if_drv_flags & IFF_DRV_RUNNING) if (sc->flags & IPW_FLAG_RUNNING)
callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc);
} }
static int static void
ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ipw_parent(struct ieee80211com *ic)
{ {
struct ipw_softc *sc = ifp->if_softc; struct ipw_softc *sc = ic->ic_softc;
struct ieee80211com *ic = ifp->if_l2com; int startall = 0;
struct ifreq *ifr = (struct ifreq *) data;
int error = 0, startall = 0;
switch (cmd) { IPW_LOCK(sc);
case SIOCSIFFLAGS: if (ic->ic_nrunning > 0) {
IPW_LOCK(sc); if (!(sc->flags & IPW_FLAG_RUNNING)) {
if (ifp->if_flags & IFF_UP) { ipw_init_locked(sc);
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { startall = 1;
ipw_init_locked(sc);
startall = 1;
}
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ipw_stop_locked(sc);
} }
IPW_UNLOCK(sc); } else if (sc->flags & IPW_FLAG_RUNNING)
if (startall) ipw_stop_locked(sc);
ieee80211_start_all(ic); IPW_UNLOCK(sc);
break; if (startall)
case SIOCGIFMEDIA: ieee80211_start_all(ic);
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
break;
case SIOCGIFADDR:
error = ether_ioctl(ifp, cmd, data);
break;
default:
error = EINVAL;
break;
}
return error;
} }
static void static void
@@ -2075,8 +2010,7 @@ ipw_load_firmware(struct ipw_softc *sc, const char *fw, int size)
static int static int
ipw_setwepkeys(struct ipw_softc *sc) ipw_setwepkeys(struct ipw_softc *sc)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ipw_wep_key wepkey; struct ipw_wep_key wepkey;
struct ieee80211_key *wk; struct ieee80211_key *wk;
@@ -2219,8 +2153,7 @@ done:
static int static int
ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan) ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
uint32_t data; uint32_t data;
int error; int error;
@@ -2235,8 +2168,7 @@ ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
static void static void
ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap) ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{ {
struct ifnet *ifp = vap->iv_ic->ic_ifp; struct ipw_softc *sc = ic->ic_softc;
struct ipw_softc *sc = ifp->if_softc;
struct ieee80211_node *ni = vap->iv_bss; struct ieee80211_node *ni = vap->iv_bss;
struct ipw_security security; struct ipw_security security;
uint32_t data; uint32_t data;
@@ -2327,9 +2259,8 @@ done:
static void static void
ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap) ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{ {
struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct ieee80211_node *ni = vap->iv_bss; struct ieee80211_node *ni = vap->iv_bss;
struct ipw_softc *sc = ifp->if_softc; struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc); IPW_LOCK(sc);
DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":"));
@@ -2363,22 +2294,20 @@ static void
ipw_init(void *priv) ipw_init(void *priv)
{ {
struct ipw_softc *sc = priv; struct ipw_softc *sc = priv;
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
IPW_LOCK(sc); IPW_LOCK(sc);
ipw_init_locked(sc); ipw_init_locked(sc);
IPW_UNLOCK(sc); IPW_UNLOCK(sc);
if (ifp->if_drv_flags & IFF_DRV_RUNNING) if (sc->flags & IPW_FLAG_RUNNING)
ieee80211_start_all(ic); /* start all vap's */ ieee80211_start_all(ic); /* start all vap's */
} }
static void static void
ipw_init_locked(struct ipw_softc *sc) ipw_init_locked(struct ipw_softc *sc)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
const struct firmware *fp; const struct firmware *fp;
const struct ipw_firmware_hdr *hdr; const struct ipw_firmware_hdr *hdr;
@@ -2462,22 +2391,19 @@ ipw_init_locked(struct ipw_softc *sc)
} }
callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc);
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->flags |= IPW_FLAG_RUNNING;
ifp->if_drv_flags |= IFF_DRV_RUNNING; sc->flags &= ~IPW_FLAG_INIT_LOCKED;
sc->flags &=~ IPW_FLAG_INIT_LOCKED;
return; return;
fail: fail:
ipw_stop_locked(sc); ipw_stop_locked(sc);
sc->flags &=~ IPW_FLAG_INIT_LOCKED; sc->flags &= ~IPW_FLAG_INIT_LOCKED;
} }
static int static int
ipw_config(struct ipw_softc *sc) ipw_config(struct ipw_softc *sc)
{ {
struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211com *ic = ifp->if_l2com;
struct ipw_configuration config; struct ipw_configuration config;
uint32_t data; uint32_t data;
int error; int error;
@@ -2522,7 +2448,7 @@ ipw_config(struct ipw_softc *sc)
IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE); IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE);
if (ic->ic_opmode == IEEE80211_M_IBSS) if (ic->ic_opmode == IEEE80211_M_IBSS)
config.flags |= htole32(IPW_CFG_IBSS_AUTO_START); config.flags |= htole32(IPW_CFG_IBSS_AUTO_START);
if (ifp->if_flags & IFF_PROMISC) if (ic->ic_promisc > 0)
config.flags |= htole32(IPW_CFG_PROMISCUOUS); config.flags |= htole32(IPW_CFG_PROMISCUOUS);
config.bss_chan = htole32(0x3fff); /* channels 1-14 */ config.bss_chan = htole32(0x3fff); /* channels 1-14 */
config.ibss_chan = htole32(0x7ff); /* channels 1-11 */ config.ibss_chan = htole32(0x7ff); /* channels 1-11 */
@@ -2580,7 +2506,6 @@ ipw_stop(void *priv)
static void static void
ipw_stop_locked(struct ipw_softc *sc) ipw_stop_locked(struct ipw_softc *sc)
{ {
struct ifnet *ifp = sc->sc_ifp;
int i; int i;
IPW_LOCK_ASSERT(sc); IPW_LOCK_ASSERT(sc);
@@ -2597,7 +2522,7 @@ ipw_stop_locked(struct ipw_softc *sc)
ipw_release_sbd(sc, &sc->stbd_list[i]); ipw_release_sbd(sc, &sc->stbd_list[i]);
sc->sc_tx_timer = 0; sc->sc_tx_timer = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); sc->flags &= ~IPW_FLAG_RUNNING;
} }
static int static int
@@ -2695,19 +2620,37 @@ ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, const uint8_t *datap,
static void static void
ipw_scan_start(struct ieee80211com *ic) ipw_scan_start(struct ieee80211com *ic)
{ {
struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ic->ic_softc;
struct ipw_softc *sc = ifp->if_softc;
IPW_LOCK(sc); IPW_LOCK(sc);
ipw_scan(sc); ipw_scan(sc);
IPW_UNLOCK(sc); IPW_UNLOCK(sc);
} }
static void
ipw_getradiocaps(struct ieee80211com *ic,
int maxchans, int *nchans, struct ieee80211_channel chans[])
{
struct ipw_softc *sc = ic->ic_softc;
uint8_t bands[IEEE80211_MODE_BYTES];
int i;
memset(bands, 0, sizeof(bands));
setbit(bands, IEEE80211_MODE_11B);
for (i = 1; i < 16; i++) {
if (sc->chanmask & (1 << i)) {
ieee80211_add_channel(chans, maxchans, nchans,
i, 0, 0, 0, bands);
}
}
}
static void static void
ipw_set_channel(struct ieee80211com *ic) ipw_set_channel(struct ieee80211com *ic)
{ {
struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ic->ic_softc;
struct ipw_softc *sc = ifp->if_softc;
IPW_LOCK(sc); IPW_LOCK(sc);
if (ic->ic_opmode == IEEE80211_M_MONITOR) { if (ic->ic_opmode == IEEE80211_M_MONITOR) {
@@ -2733,8 +2676,7 @@ ipw_scan_mindwell(struct ieee80211_scan_state *ss)
static void static void
ipw_scan_end(struct ieee80211com *ic) ipw_scan_end(struct ieee80211com *ic)
{ {
struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ic->ic_softc;
struct ipw_softc *sc = ifp->if_softc;
IPW_LOCK(sc); IPW_LOCK(sc);
sc->flags &= ~IPW_FLAG_SCANNING; sc->flags &= ~IPW_FLAG_SCANNING;
@@ -1,4 +1,4 @@
/* $FreeBSD$ */ /* $FreeBSD: releng/11.1/sys/dev/ipw/if_ipwreg.h 172567 2007-10-12 05:23:00Z thompsa $ */
/*- /*-
* Copyright (c) 2004-2006 * Copyright (c) 2004-2006
@@ -1,4 +1,4 @@
/* $FreeBSD$ */ /* $FreeBSD: releng/11.1/sys/dev/ipw/if_ipwvar.h 300239 2016-05-19 22:19:35Z avos $ */
/*- /*-
* Copyright (c) 2004-2006 * Copyright (c) 2004-2006
@@ -87,7 +87,8 @@ struct ipw_vap {
#define IPW_VAP(vap) ((struct ipw_vap *)(vap)) #define IPW_VAP(vap) ((struct ipw_vap *)(vap))
struct ipw_softc { struct ipw_softc {
struct ifnet *sc_ifp; struct ieee80211com sc_ic;
struct mbufq sc_snd;
device_t sc_dev; device_t sc_dev;
struct mtx sc_mtx; struct mtx sc_mtx;
@@ -104,9 +105,8 @@ struct ipw_softc {
#define IPW_FLAG_BUSY 0x0040 #define IPW_FLAG_BUSY 0x0040
#define IPW_FLAG_ASSOCIATING 0x0080 #define IPW_FLAG_ASSOCIATING 0x0080
#define IPW_FLAG_ASSOCIATED 0x0100 #define IPW_FLAG_ASSOCIATED 0x0100
#define IPW_FLAG_RUNNING 0x0200
int irq_rid;
int mem_rid;
struct resource *irq; struct resource *irq;
struct resource *mem; struct resource *mem;
bus_space_tag_t sc_st; bus_space_tag_t sc_st;
@@ -157,6 +157,8 @@ struct ipw_softc {
uint32_t rxcur; uint32_t rxcur;
int txfree; int txfree;
uint16_t chanmask;
struct ipw_rx_radiotap_header sc_rxtap; struct ipw_rx_radiotap_header sc_rxtap;
struct ipw_tx_radiotap_header sc_txtap; struct ipw_tx_radiotap_header sc_txtap;
@@ -23,8 +23,11 @@ NO_HAIKU_FBSD_MII_DRIVER();
NO_HAIKU_REENABLE_INTERRUPTS(); NO_HAIKU_REENABLE_INTERRUPTS();
HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_SWI_TASKQUEUE | FBSD_WLAN); HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_SWI_TASKQUEUE | FBSD_WLAN);
HAIKU_FIRMWARE_VERSION(130); HAIKU_FIRMWARE_VERSION(130);
HAIKU_FIRMWARE_NAME_MAP(3) = {{"ipw_bss", "ipw2100-1.3.fw"}, HAIKU_FIRMWARE_NAME_MAP(3) = {
{"ipw_ibss", "ipw2100-1.3-i.fw"}, {"ipw_monitor", "ipw2100-1.3-p.fw"}}; {"ipw_bss", "ipw2100-1.3.fw"},
{"ipw_ibss", "ipw2100-1.3-i.fw"},
{"ipw_monitor", "ipw2100-1.3-p.fw"}
};
int int