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 ;
# 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 ;
# FreeBSD 9.3 drivers
@@ -13,6 +12,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network wlan wavelanwifi ;
# 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 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 iprowifi4965 ;
@@ -1,14 +1,14 @@
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 ;
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 ]
-Wno-format
-Wno-unused
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
-Wno-format
-Wno-unused
-Wno-uninitialized ;
UseHeaders [ FDirName $(SUBDIR) ] : true ;
@@ -19,8 +19,8 @@ KernelAddon iprowifi2100 :
if_ipw.c
glue.c
:
libfreebsd_wlan.a
libfreebsd_network.a
libfreebsd11_wlan.a
libfreebsd11_network.a
;
# Note: Due to licensing restrictions, we can only distribute the archive.
@@ -1,5 +1,3 @@
/* $FreeBSD$ */
/*-
* Copyright (c) 2004-2006
* Damien Bergamini <[email protected]>. All rights reserved.
@@ -30,7 +28,7 @@
*/
#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
@@ -62,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/ethernet.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 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_chanmask(struct ipw_softc *);
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_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 const char * ipw_cmdname(int);
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 *);
static int ipw_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void ipw_start(struct ifnet *);
static void ipw_start_locked(struct ifnet *);
static int ipw_transmit(struct ieee80211com *, struct mbuf *);
static void ipw_start(struct ipw_softc *);
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 int ipw_enable(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 void ipw_scan_start(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_scan_curchan(struct ieee80211_scan_state *,
unsigned long maxdwell);
@@ -186,7 +188,7 @@ static device_method_t ipw_methods[] = {
DEVMETHOD(device_suspend, ipw_suspend),
DEVMETHOD(device_resume, ipw_resume),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t ipw_driver = {
@@ -197,7 +199,7 @@ static driver_t ipw_driver = {
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);
@@ -210,48 +212,36 @@ ipw_probe(device_t dev)
if (pci_get_vendor(dev) == ident->vendor &&
pci_get_device(dev) == ident->device) {
device_set_desc(dev, ident->name);
return 0;
return (BUS_PROBE_DEFAULT);
}
}
return ENXIO;
}
/* Base Address Register */
#define IPW_PCI_BAR0 0x10
static int
ipw_attach(device_t dev)
{
struct ipw_softc *sc = device_get_softc(dev);
struct ifnet *ifp;
struct ieee80211com *ic;
struct ieee80211_channel *c;
struct ieee80211com *ic = &sc->sc_ic;
uint16_t val;
int error, i;
uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
mbufq_init(&sc->sc_snd, ifqmaxlen);
TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc);
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);
/* enable bus-mastering */
pci_enable_busmaster(dev);
sc->mem_rid = IPW_PCI_BAR0;
sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
RF_ACTIVE);
i = PCIR_BAR(0);
sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE);
if (sc->mem == NULL) {
device_printf(dev, "could not allocate memory resource\n");
goto fail;
@@ -260,8 +250,8 @@ ipw_attach(device_t dev)
sc->sc_st = rman_get_bustag(sc->mem);
sc->sc_sh = rman_get_bushandle(sc->mem);
sc->irq_rid = 0;
sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
i = 0;
sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
RF_ACTIVE | RF_SHAREABLE);
if (sc->irq == NULL) {
device_printf(dev, "could not allocate interrupt resource\n");
@@ -278,24 +268,8 @@ ipw_attach(device_t dev)
goto fail2;
}
ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
if (ifp == NULL) {
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_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_DS;
@@ -311,42 +285,35 @@ ipw_attach(device_t dev)
/* read MAC address from EEPROM */
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0);
macaddr[0] = val >> 8;
macaddr[1] = val & 0xff;
ic->ic_macaddr[0] = val >> 8;
ic->ic_macaddr[1] = val & 0xff;
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 1);
macaddr[2] = val >> 8;
macaddr[3] = val & 0xff;
ic->ic_macaddr[2] = val >> 8;
ic->ic_macaddr[3] = val & 0xff;
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 2);
macaddr[4] = val >> 8;
macaddr[5] = val & 0xff;
ic->ic_macaddr[4] = val >> 8;
ic->ic_macaddr[5] = val & 0xff;
/* 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;
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;
}
}
sc->chanmask = ipw_read_chanmask(sc);
ipw_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
ic->ic_channels);
/* check support for radio transmitter switch in EEPROM */
if (!(ipw_read_prom_word(sc, IPW_EEPROM_RADIO) & 8))
sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH;
ieee80211_ifattach(ic, macaddr);
ieee80211_ifattach(ic);
ic->ic_scan_start = ipw_scan_start;
ic->ic_scan_end = ipw_scan_end;
ic->ic_getradiocaps = ipw_getradiocaps;
ic->ic_set_channel = ipw_set_channel;
ic->ic_scan_curchan = ipw_scan_curchan;
ic->ic_scan_mindwell = ipw_scan_mindwell;
ic->ic_raw_xmit = ipw_raw_xmit;
ic->ic_vap_create = ipw_vap_create;
ic->ic_vap_delete = ipw_vap_delete;
ic->ic_transmit = ipw_transmit;
ic->ic_parent = ipw_parent;
ieee80211_radiotap_attach(ic,
&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);
if (error != 0) {
device_printf(dev, "could not set up interrupt\n");
goto fail4;
goto fail3;
}
if (bootverbose)
ieee80211_announce(ic);
return 0;
fail4:
if_free(ifp);
fail3:
ipw_release(sc);
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:
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:
mtx_destroy(&sc->sc_mtx);
return ENXIO;
@@ -398,8 +364,9 @@ static int
ipw_detach(device_t dev)
{
struct ipw_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
ieee80211_draintask(ic, &sc->sc_init_task);
ipw_stop(sc);
@@ -407,15 +374,14 @@ ipw_detach(device_t dev)
ieee80211_ifdetach(ic);
callout_drain(&sc->sc_wdtimer);
mbufq_drain(&sc->sc_snd);
ipw_release(sc);
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
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);
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
if_free(ifp);
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem),
sc->mem);
if (sc->sc_firmware != NULL) {
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 mac[IEEE80211_ADDR_LEN])
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_softc *sc = ic->ic_softc;
struct ipw_vap *ivp;
struct ieee80211vap *vap;
const struct firmware *fp;
@@ -492,19 +457,17 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return NULL;
}
ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap),
M_80211_VAP, M_NOWAIT | M_ZERO);
if (ivp == NULL)
return NULL;
ivp = malloc(sizeof(struct ipw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
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 */
ivp->newstate = vap->iv_newstate;
vap->iv_newstate = ipw_newstate;
/* 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;
return vap;
}
@@ -758,11 +721,8 @@ ipw_release(struct ipw_softc *sc)
}
if (sc->tbd_dmat != NULL) {
if (sc->stbd_list != NULL) {
bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map);
bus_dmamem_free(sc->tbd_dmat, sc->tbd_list,
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_dma_tag_destroy(sc->tbd_dmat);
}
@@ -835,7 +795,7 @@ static int
ipw_suspend(device_t 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);
return 0;
@@ -845,7 +805,7 @@ static int
ipw_resume(device_t 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);
@@ -874,7 +834,7 @@ ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
struct ieee80211vap *vap = ifp->if_softc;
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 */
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 ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_softc *sc = ic->ic_softc;
enum ieee80211_state ostate;
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);
}
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
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)
{
#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state]
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t state;
@@ -1126,8 +1097,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
static void
ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
ic->ic_curchan = chan;
ieee80211_radiotap_chan_change(ic);
@@ -1140,8 +1110,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
static void
ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c;
struct ieee80211_frame *wh;
uint8_t subtype;
@@ -1186,8 +1155,7 @@ static void
ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *mnew, *m;
struct ieee80211_node *ni;
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);
if (mnew == NULL) {
ifp->if_ierrors++;
counter_u64_add(ic->ic_ierrors, 1);
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",
device_get_name(sc->sc_dev));
}
ifp->if_ierrors++;
counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -1241,9 +1209,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
m = sbuf->m;
sbuf->m = mnew;
sbd->bd->physaddr = htole32(physaddr);
/* finalize mbuf */
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = le32toh(status->len);
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
ipw_tx_intr(struct ipw_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
struct ipw_soft_bd *sbd;
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) {
sbd = &sc->stbd_list[i];
if (sbd->type == IPW_SBD_TYPE_DATA)
ifp->if_opackets++;
ipw_release_sbd(sc, sbd);
sc->txfree++;
}
@@ -1394,15 +1354,13 @@ ipw_tx_intr(struct ipw_softc *sc)
/* remember what the firmware has processed */
sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
ipw_start_locked(ifp);
ipw_start(sc);
}
static void
ipw_fatal_error_intr(struct ipw_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
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 *
ipw_cmdname(int cmd)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
static const struct {
int cmd;
const char *name;
@@ -1507,12 +1464,11 @@ ipw_cmdname(int cmd)
static char buf[12];
int i;
for (i = 0; i < N(cmds); i++)
for (i = 0; i < nitems(cmds); i++)
if (cmds[i].cmd == cmd)
return cmds[i].name;
snprintf(buf, sizeof(buf), "%u", cmd);
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);
/* Print the data buffer in the higher debug level */
if (ipw_debug >= 9 && len > 0) {
#ifdef __HAIKU__
int i;
printf(" data: 0x");
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("\n");
@@ -1597,10 +1548,9 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len)
}
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 = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
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 *);
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m0);
if (k == NULL) {
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.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.keyidx = 0;
shdr->hdr.keysz = 0;
@@ -1754,38 +1704,42 @@ ipw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
}
static void
ipw_start(struct ifnet *ifp)
static int
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_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);
return (0);
}
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 mbuf *m;
IPW_LOCK_ASSERT(sc);
for (;;) {
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
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;
}
while (sc->txfree < 1 + IPW_MAX_NSEG &&
(m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
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);
ifp->if_oerrors++;
break;
}
/* start watchdog timer */
@@ -1797,15 +1751,14 @@ static void
ipw_watchdog(void *arg)
{
struct ipw_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
IPW_LOCK_ASSERT(sc);
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
if_printf(ifp, "device timeout\n");
ifp->if_oerrors++;
device_printf(sc->sc_dev, "device timeout\n");
counter_u64_add(ic->ic_oerrors, 1);
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);
}
static int
ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
static void
ipw_parent(struct ieee80211com *ic)
{
struct ipw_softc *sc = ifp->if_softc;
struct ieee80211com *ic = ifp->if_l2com;
struct ifreq *ifr = (struct ifreq *) data;
int error = 0, startall = 0;
struct ipw_softc *sc = ic->ic_softc;
int startall = 0;
switch (cmd) {
case SIOCSIFFLAGS:
IPW_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
ipw_init_locked(sc);
startall = 1;
}
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ipw_stop_locked(sc);
IPW_LOCK(sc);
if (ic->ic_nrunning > 0) {
if (!(sc->flags & IPW_FLAG_RUNNING)) {
ipw_init_locked(sc);
startall = 1;
}
IPW_UNLOCK(sc);
if (startall)
ieee80211_start_all(ic);
break;
case SIOCGIFMEDIA:
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;
} else if (sc->flags & IPW_FLAG_RUNNING)
ipw_stop_locked(sc);
IPW_UNLOCK(sc);
if (startall)
ieee80211_start_all(ic);
}
static void
@@ -2075,8 +2010,7 @@ ipw_load_firmware(struct ipw_softc *sc, const char *fw, int size)
static int
ipw_setwepkeys(struct ipw_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ipw_wep_key wepkey;
struct ieee80211_key *wk;
@@ -2219,8 +2153,7 @@ done:
static int
ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
uint32_t data;
int error;
@@ -2235,8 +2168,7 @@ ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
static void
ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{
struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_softc *sc = ic->ic_softc;
struct ieee80211_node *ni = vap->iv_bss;
struct ipw_security security;
uint32_t data;
@@ -2327,9 +2259,8 @@ done:
static void
ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{
struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct ieee80211_node *ni = vap->iv_bss;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":"));
@@ -2363,22 +2294,20 @@ static void
ipw_init(void *priv)
{
struct ipw_softc *sc = priv;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
IPW_LOCK(sc);
ipw_init_locked(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 */
}
static void
ipw_init_locked(struct ipw_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
const struct firmware *fp;
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);
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->flags &=~ IPW_FLAG_INIT_LOCKED;
sc->flags |= IPW_FLAG_RUNNING;
sc->flags &= ~IPW_FLAG_INIT_LOCKED;
return;
fail:
ipw_stop_locked(sc);
sc->flags &=~ IPW_FLAG_INIT_LOCKED;
sc->flags &= ~IPW_FLAG_INIT_LOCKED;
}
static int
ipw_config(struct ipw_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211com *ic = &sc->sc_ic;
struct ipw_configuration config;
uint32_t data;
int error;
@@ -2522,7 +2448,7 @@ ipw_config(struct ipw_softc *sc)
IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE);
if (ic->ic_opmode == IEEE80211_M_IBSS)
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.bss_chan = htole32(0x3fff); /* channels 1-14 */
config.ibss_chan = htole32(0x7ff); /* channels 1-11 */
@@ -2580,7 +2506,6 @@ ipw_stop(void *priv)
static void
ipw_stop_locked(struct ipw_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
int i;
IPW_LOCK_ASSERT(sc);
@@ -2597,7 +2522,7 @@ ipw_stop_locked(struct ipw_softc *sc)
ipw_release_sbd(sc, &sc->stbd_list[i]);
sc->sc_tx_timer = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->flags &= ~IPW_FLAG_RUNNING;
}
static int
@@ -2695,19 +2620,37 @@ ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, const uint8_t *datap,
static void
ipw_scan_start(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
ipw_scan(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
ipw_set_channel(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
if (ic->ic_opmode == IEEE80211_M_MONITOR) {
@@ -2733,8 +2676,7 @@ ipw_scan_mindwell(struct ieee80211_scan_state *ss)
static void
ipw_scan_end(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
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
@@ -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
@@ -87,7 +87,8 @@ struct ipw_vap {
#define IPW_VAP(vap) ((struct ipw_vap *)(vap))
struct ipw_softc {
struct ifnet *sc_ifp;
struct ieee80211com sc_ic;
struct mbufq sc_snd;
device_t sc_dev;
struct mtx sc_mtx;
@@ -104,9 +105,8 @@ struct ipw_softc {
#define IPW_FLAG_BUSY 0x0040
#define IPW_FLAG_ASSOCIATING 0x0080
#define IPW_FLAG_ASSOCIATED 0x0100
#define IPW_FLAG_RUNNING 0x0200
int irq_rid;
int mem_rid;
struct resource *irq;
struct resource *mem;
bus_space_tag_t sc_st;
@@ -157,6 +157,8 @@ struct ipw_softc {
uint32_t rxcur;
int txfree;
uint16_t chanmask;
struct ipw_rx_radiotap_header sc_rxtap;
struct ipw_tx_radiotap_header sc_txtap;
@@ -23,8 +23,11 @@ NO_HAIKU_FBSD_MII_DRIVER();
NO_HAIKU_REENABLE_INTERRUPTS();
HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_SWI_TASKQUEUE | FBSD_WLAN);
HAIKU_FIRMWARE_VERSION(130);
HAIKU_FIRMWARE_NAME_MAP(3) = {{"ipw_bss", "ipw2100-1.3.fw"},
{"ipw_ibss", "ipw2100-1.3-i.fw"}, {"ipw_monitor", "ipw2100-1.3-p.fw"}};
HAIKU_FIRMWARE_NAME_MAP(3) = {
{"ipw_bss", "ipw2100-1.3.fw"},
{"ipw_ibss", "ipw2100-1.3-i.fw"},
{"ipw_monitor", "ipw2100-1.3-p.fw"}
};
int