Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/iwn/if_iwn.c
Context not available. | |||||
static void iwn_xmit_task(void *arg0, int pending); | static void iwn_xmit_task(void *arg0, int pending); | ||||
static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *, | static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *, | ||||
const struct ieee80211_bpf_params *); | const struct ieee80211_bpf_params *); | ||||
static void iwn_start(struct ifnet *); | static int iwn_transmit(struct ieee80211com *, struct mbuf *); | ||||
static void iwn_start_locked(struct ifnet *); | static void iwn_start_locked(struct iwn_softc *); | ||||
static void iwn_watchdog(void *); | static void iwn_watchdog(void *); | ||||
static int iwn_ioctl(struct ifnet *, u_long, caddr_t); | static int iwn_ioctl(struct ieee80211com *, u_long , void *); | ||||
static void iwn_parent(struct ieee80211com *); | |||||
static int iwn_cmd(struct iwn_softc *, int, const void *, int, int); | static int iwn_cmd(struct iwn_softc *, int, const void *, int, int); | ||||
static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *, | static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *, | ||||
int); | int); | ||||
Context not available. | |||||
static void iwn_radio_off(void *, int); | static void iwn_radio_off(void *, int); | ||||
static void iwn_panicked(void *, int); | static void iwn_panicked(void *, int); | ||||
static void iwn_init_locked(struct iwn_softc *); | static void iwn_init_locked(struct iwn_softc *); | ||||
static void iwn_init(void *); | static void iwn_init(struct iwn_softc *); | ||||
static void iwn_stop_locked(struct iwn_softc *); | static void iwn_stop_locked(struct iwn_softc *); | ||||
static void iwn_stop(struct iwn_softc *); | static void iwn_stop(struct iwn_softc *); | ||||
static void iwn_scan_start(struct ieee80211com *); | static void iwn_scan_start(struct ieee80211com *); | ||||
Context not available. | |||||
{ | { | ||||
struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev); | struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev); | ||||
struct ieee80211com *ic; | struct ieee80211com *ic; | ||||
struct ifnet *ifp; | |||||
int i, error, rid; | int i, error, rid; | ||||
uint8_t macaddr[IEEE80211_ADDR_LEN]; | |||||
sc->sc_dev = dev; | sc->sc_dev = dev; | ||||
Context not available. | |||||
} | } | ||||
IWN_LOCK_INIT(sc); | IWN_LOCK_INIT(sc); | ||||
mbufq_init(&sc->sc_snd, ifqmaxlen); | |||||
/* Read hardware revision and attach. */ | /* Read hardware revision and attach. */ | ||||
sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> IWN_HW_REV_TYPE_SHIFT) | sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> IWN_HW_REV_TYPE_SHIFT) | ||||
Context not available. | |||||
/* Clear pending interrupts. */ | /* Clear pending interrupts. */ | ||||
IWN_WRITE(sc, IWN_INT, 0xffffffff); | IWN_WRITE(sc, IWN_INT, 0xffffffff); | ||||
ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); | ic = &sc->sc_ic; | ||||
if (ifp == NULL) { | |||||
device_printf(dev, "can not allocate ifnet structure\n"); | |||||
goto fail; | |||||
} | |||||
ic = ifp->if_l2com; | |||||
ic->ic_ifp = ifp; | |||||
ic->ic_softc = sc; | ic->ic_softc = sc; | ||||
ic->ic_name = device_get_nameunit(dev); | ic->ic_name = device_get_nameunit(dev); | ||||
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ | ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ | ||||
Context not available. | |||||
; | ; | ||||
/* Read MAC address, channels, etc from EEPROM. */ | /* Read MAC address, channels, etc from EEPROM. */ | ||||
if ((error = iwn_read_eeprom(sc, macaddr)) != 0) { | if ((error = iwn_read_eeprom(sc, ic->ic_macaddr)) != 0) { | ||||
device_printf(dev, "could not read EEPROM, error %d\n", | device_printf(dev, "could not read EEPROM, error %d\n", | ||||
error); | error); | ||||
goto fail; | goto fail; | ||||
Context not available. | |||||
if (bootverbose) { | if (bootverbose) { | ||||
device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n", | device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n", | ||||
sc->ntxchains, sc->nrxchains, sc->eeprom_domain, | sc->ntxchains, sc->nrxchains, sc->eeprom_domain, | ||||
macaddr, ":"); | ic->ic_macaddr, ":"); | ||||
} | } | ||||
if (sc->sc_flags & IWN_FLAG_HAS_11N) { | if (sc->sc_flags & IWN_FLAG_HAS_11N) { | ||||
Context not available. | |||||
; | ; | ||||
} | } | ||||
if_initname(ifp, device_get_name(dev), device_get_unit(dev)); | ieee80211_ifattach(ic); | ||||
ifp->if_softc = sc; | |||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; | |||||
ifp->if_init = iwn_init; | |||||
ifp->if_ioctl = iwn_ioctl; | |||||
ifp->if_start = iwn_start; | |||||
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); | |||||
ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; | |||||
IFQ_SET_READY(&ifp->if_snd); | |||||
ieee80211_ifattach(ic, macaddr); | |||||
ic->ic_vap_create = iwn_vap_create; | ic->ic_vap_create = iwn_vap_create; | ||||
ic->ic_ioctl = iwn_ioctl; | |||||
ic->ic_parent = iwn_parent; | |||||
ic->ic_vap_delete = iwn_vap_delete; | ic->ic_vap_delete = iwn_vap_delete; | ||||
ic->ic_transmit = iwn_transmit; | |||||
ic->ic_raw_xmit = iwn_raw_xmit; | ic->ic_raw_xmit = iwn_raw_xmit; | ||||
ic->ic_node_alloc = iwn_node_alloc; | ic->ic_node_alloc = iwn_node_alloc; | ||||
sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start; | sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start; | ||||
Context not available. | |||||
static void | static void | ||||
iwn_radiotap_attach(struct iwn_softc *sc) | iwn_radiotap_attach(struct iwn_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | ||||
ieee80211_radiotap_attach(ic, | ieee80211_radiotap_attach(&sc->sc_ic, | ||||
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), | &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), | ||||
IWN_TX_RADIOTAP_PRESENT, | IWN_TX_RADIOTAP_PRESENT, | ||||
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), | &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), | ||||
Context not available. | |||||
struct iwn_softc *sc = ic->ic_softc; | struct iwn_softc *sc = ic->ic_softc; | ||||
struct iwn_vap *ivp; | struct iwn_vap *ivp; | ||||
struct ieee80211vap *vap; | struct ieee80211vap *vap; | ||||
uint8_t mac1[IEEE80211_ADDR_LEN]; | |||||
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ | if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ | ||||
return NULL; | return NULL; | ||||
IEEE80211_ADDR_COPY(mac1, mac); | ivp = malloc(sizeof(struct iwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); | ||||
ivp = (struct iwn_vap *) malloc(sizeof(struct iwn_vap), | |||||
M_80211_VAP, M_NOWAIT | M_ZERO); | |||||
if (ivp == NULL) | |||||
return NULL; | |||||
vap = &ivp->iv_vap; | vap = &ivp->iv_vap; | ||||
ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac1); | ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); | ||||
ivp->ctx = IWN_RXON_BSS_CTX; | ivp->ctx = IWN_RXON_BSS_CTX; | ||||
IEEE80211_ADDR_COPY(ivp->macaddr, mac1); | |||||
vap->iv_bmissthreshold = 10; /* override default */ | vap->iv_bmissthreshold = 10; /* override default */ | ||||
/* Override with driver methods. */ | /* Override with driver methods. */ | ||||
ivp->iv_newstate = vap->iv_newstate; | ivp->iv_newstate = vap->iv_newstate; | ||||
Context not available. | |||||
ieee80211_ratectl_init(vap); | ieee80211_ratectl_init(vap); | ||||
/* Complete setup. */ | /* Complete setup. */ | ||||
ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status); | ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status, | ||||
mac); | |||||
ic->ic_opmode = opmode; | ic->ic_opmode = opmode; | ||||
return vap; | return vap; | ||||
} | } | ||||
Context not available. | |||||
iwn_detach(device_t dev) | iwn_detach(device_t dev) | ||||
{ | { | ||||
struct iwn_softc *sc = device_get_softc(dev); | struct iwn_softc *sc = device_get_softc(dev); | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct ieee80211com *ic; | |||||
int qid; | int qid; | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | ||||
if (ifp != NULL) { | if (sc->sc_ic.ic_softc != NULL) { | ||||
ic = ifp->if_l2com; | |||||
/* Free the mbuf queue and node references */ | /* Free the mbuf queue and node references */ | ||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
iwn_xmit_queue_drain(sc); | iwn_xmit_queue_drain(sc); | ||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
ieee80211_draintask(ic, &sc->sc_reinit_task); | ieee80211_draintask(&sc->sc_ic, &sc->sc_reinit_task); | ||||
ieee80211_draintask(ic, &sc->sc_radioon_task); | ieee80211_draintask(&sc->sc_ic, &sc->sc_radioon_task); | ||||
ieee80211_draintask(ic, &sc->sc_radiooff_task); | ieee80211_draintask(&sc->sc_ic, &sc->sc_radiooff_task); | ||||
iwn_stop(sc); | iwn_stop(sc); | ||||
taskqueue_drain_all(sc->sc_tq); | taskqueue_drain_all(sc->sc_tq); | ||||
Context not available. | |||||
callout_drain(&sc->watchdog_to); | callout_drain(&sc->watchdog_to); | ||||
callout_drain(&sc->calib_to); | callout_drain(&sc->calib_to); | ||||
ieee80211_ifdetach(ic); | ieee80211_ifdetach(&sc->sc_ic); | ||||
} | } | ||||
mbufq_drain(&sc->sc_snd); | |||||
/* Uninstall interrupt handler. */ | /* Uninstall interrupt handler. */ | ||||
if (sc->irq != NULL) { | if (sc->irq != NULL) { | ||||
bus_teardown_intr(dev, sc->irq, sc->sc_ih); | bus_teardown_intr(dev, sc->irq, sc->sc_ih); | ||||
Context not available. | |||||
bus_release_resource(dev, SYS_RES_MEMORY, | bus_release_resource(dev, SYS_RES_MEMORY, | ||||
rman_get_rid(sc->mem), sc->mem); | rman_get_rid(sc->mem), sc->mem); | ||||
if (ifp != NULL) | |||||
if_free(ifp); | |||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n", __func__); | ||||
IWN_LOCK_DESTROY(sc); | IWN_LOCK_DESTROY(sc); | ||||
return 0; | return 0; | ||||
Context not available. | |||||
iwn_suspend(device_t dev) | iwn_suspend(device_t dev) | ||||
{ | { | ||||
struct iwn_softc *sc = device_get_softc(dev); | struct iwn_softc *sc = device_get_softc(dev); | ||||
struct ieee80211com *ic = sc->sc_ifp->if_l2com; | |||||
ieee80211_suspend_all(ic); | ieee80211_suspend_all(&sc->sc_ic); | ||||
return 0; | return 0; | ||||
} | } | ||||
Context not available. | |||||
iwn_resume(device_t dev) | iwn_resume(device_t dev) | ||||
{ | { | ||||
struct iwn_softc *sc = device_get_softc(dev); | struct iwn_softc *sc = device_get_softc(dev); | ||||
struct ieee80211com *ic = sc->sc_ifp->if_l2com; | |||||
/* Clear device-specific "PCI retry timeout" register (41h). */ | /* Clear device-specific "PCI retry timeout" register (41h). */ | ||||
pci_write_config(dev, 0x41, 0, 1); | pci_write_config(dev, 0x41, 0, 1); | ||||
ieee80211_resume_all(ic); | ieee80211_resume_all(&sc->sc_ic); | ||||
return 0; | return 0; | ||||
} | } | ||||
Context not available. | |||||
static void | static void | ||||
iwn_read_eeprom_band(struct iwn_softc *sc, int n) | iwn_read_eeprom_band(struct iwn_softc *sc, int n) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct iwn_eeprom_chan *channels = sc->eeprom_channels[n]; | struct iwn_eeprom_chan *channels = sc->eeprom_channels[n]; | ||||
const struct iwn_chan_band *band = &iwn_bands[n]; | const struct iwn_chan_band *band = &iwn_bands[n]; | ||||
struct ieee80211_channel *c; | struct ieee80211_channel *c; | ||||
Context not available. | |||||
static void | static void | ||||
iwn_read_eeprom_ht40(struct iwn_softc *sc, int n) | iwn_read_eeprom_ht40(struct iwn_softc *sc, int n) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct iwn_eeprom_chan *channels = sc->eeprom_channels[n]; | struct iwn_eeprom_chan *channels = sc->eeprom_channels[n]; | ||||
const struct iwn_chan_band *band = &iwn_bands[n]; | const struct iwn_chan_band *band = &iwn_bands[n]; | ||||
struct ieee80211_channel *c, *cent, *extc; | struct ieee80211_channel *c, *cent, *extc; | ||||
Context not available. | |||||
static void | static void | ||||
iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr) | iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n], | iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n], | ||||
iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan)); | iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan)); | ||||
Context not available. | |||||
iwn_read_eeprom_enhinfo(struct iwn_softc *sc) | iwn_read_eeprom_enhinfo(struct iwn_softc *sc) | ||||
{ | { | ||||
struct iwn_eeprom_enhinfo enhinfo[35]; | struct iwn_eeprom_enhinfo enhinfo[35]; | ||||
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; | ||||
uint16_t val, base; | uint16_t val, base; | ||||
int8_t maxpwr; | int8_t maxpwr; | ||||
Context not available. | |||||
struct iwn_rx_data *data) | struct iwn_rx_data *data) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct iwn_rx_ring *ring = &sc->rxq; | struct iwn_rx_ring *ring = &sc->rxq; | ||||
struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
struct ieee80211_node *ni; | struct ieee80211_node *ni; | ||||
Context not available. | |||||
if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) { | if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) { | ||||
DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n", | DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n", | ||||
__func__, flags); | __func__, flags); | ||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | counter_u64_add(ic->ic_ierrors, 1); | ||||
return; | return; | ||||
} | } | ||||
/* Discard frames that are too short. */ | /* Discard frames that are too short. */ | ||||
Context not available. | |||||
if (len < sizeof (struct ieee80211_frame_ack)) { | if (len < sizeof (struct ieee80211_frame_ack)) { | ||||
DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n", | DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n", | ||||
__func__, len); | __func__, len); | ||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | counter_u64_add(ic->ic_ierrors, 1); | ||||
return; | return; | ||||
} | } | ||||
Context not available. | |||||
if (m1 == NULL) { | if (m1 == NULL) { | ||||
DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n", | DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n", | ||||
__func__); | __func__); | ||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | counter_u64_add(ic->ic_ierrors, 1); | ||||
return; | return; | ||||
} | } | ||||
bus_dmamap_unload(ring->data_dmat, data->map); | bus_dmamap_unload(ring->data_dmat, data->map); | ||||
Context not available. | |||||
ring->desc[ring->cur] = htole32(paddr >> 8); | ring->desc[ring->cur] = htole32(paddr >> 8); | ||||
bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map, | bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map, | ||||
BUS_DMASYNC_PREWRITE); | BUS_DMASYNC_PREWRITE); | ||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | counter_u64_add(ic->ic_ierrors, 1); | ||||
return; | return; | ||||
} | } | ||||
Context not available. | |||||
BUS_DMASYNC_PREWRITE); | BUS_DMASYNC_PREWRITE); | ||||
/* Finalize mbuf. */ | /* Finalize mbuf. */ | ||||
m->m_pkthdr.rcvif = ifp; | |||||
m->m_data = head; | m->m_data = head; | ||||
m->m_pkthdr.len = m->m_len = len; | m->m_pkthdr.len = m->m_len = len; | ||||
Context not available. | |||||
struct iwn_rx_data *data) | struct iwn_rx_data *data) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct iwn_node *wn; | struct iwn_node *wn; | ||||
struct ieee80211_node *ni; | struct ieee80211_node *ni; | ||||
struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1); | struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1); | ||||
Context not available. | |||||
bitmap = (le64toh(ba->bitmap) >> shift) & wn->agg[tid].bitmap; | bitmap = (le64toh(ba->bitmap) >> shift) & wn->agg[tid].bitmap; | ||||
for (i = 0; bitmap; i++) { | for (i = 0; bitmap; i++) { | ||||
if ((bitmap & 1) == 0) { | if ((bitmap & 1) == 0) { | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||
tx_err ++; | tx_err ++; | ||||
ieee80211_ratectl_tx_complete(ni->ni_vap, ni, | ieee80211_ratectl_tx_complete(ni->ni_vap, ni, | ||||
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); | IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); | ||||
} else { | } else { | ||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | |||||
tx_ok ++; | tx_ok ++; | ||||
ieee80211_ratectl_tx_complete(ni->ni_vap, ni, | ieee80211_ratectl_tx_complete(ni->ni_vap, ni, | ||||
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); | IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); | ||||
Context not available. | |||||
struct iwn_rx_data *data) | struct iwn_rx_data *data) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
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 iwn_calib_state *calib = &sc->calib; | struct iwn_calib_state *calib = &sc->calib; | ||||
struct iwn_stats *stats = (struct iwn_stats *)(desc + 1); | struct iwn_stats *stats = (struct iwn_stats *)(desc + 1); | ||||
Context not available. | |||||
iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, | iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, | ||||
uint8_t status) | uint8_t status) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf]; | struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf]; | ||||
struct iwn_tx_data *data = &ring->data[desc->idx]; | struct iwn_tx_data *data = &ring->data[desc->idx]; | ||||
struct mbuf *m; | struct mbuf *m; | ||||
Context not available. | |||||
/* | /* | ||||
* Update rate control statistics for the node. | * Update rate control statistics for the node. | ||||
*/ | */ | ||||
if (status & IWN_TX_FAIL) { | if (status & IWN_TX_FAIL) | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||
ieee80211_ratectl_tx_complete(vap, ni, | ieee80211_ratectl_tx_complete(vap, ni, | ||||
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); | IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); | ||||
} else { | else | ||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | |||||
ieee80211_ratectl_tx_complete(vap, ni, | ieee80211_ratectl_tx_complete(vap, ni, | ||||
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); | IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); | ||||
} | |||||
/* | /* | ||||
* Channels marked for "radar" require traffic to be received | * Channels marked for "radar" require traffic to be received | ||||
Context not available. | |||||
sc->sc_tx_timer = 0; | sc->sc_tx_timer = 0; | ||||
if (--ring->queued < IWN_TX_RING_LOMARK) { | if (--ring->queued < IWN_TX_RING_LOMARK) { | ||||
sc->qfullmsk &= ~(1 << ring->qid); | sc->qfullmsk &= ~(1 << ring->qid); | ||||
if (sc->qfullmsk == 0 && | if (sc->qfullmsk == 0) | ||||
(ifp->if_drv_flags & IFF_DRV_OACTIVE)) { | iwn_start_locked(sc); | ||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | |||||
iwn_start_locked(ifp); | |||||
} | |||||
} | } | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); | ||||
Context not available. | |||||
int ackfailcnt, void *stat) | int ackfailcnt, void *stat) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct iwn_tx_ring *ring = &sc->txq[qid]; | struct iwn_tx_ring *ring = &sc->txq[qid]; | ||||
struct iwn_tx_data *data; | struct iwn_tx_data *data; | ||||
struct mbuf *m; | struct mbuf *m; | ||||
Context not available. | |||||
sc->sc_tx_timer = 0; | sc->sc_tx_timer = 0; | ||||
if (ring->queued < IWN_TX_RING_LOMARK) { | if (ring->queued < IWN_TX_RING_LOMARK) { | ||||
sc->qfullmsk &= ~(1 << ring->qid); | sc->qfullmsk &= ~(1 << ring->qid); | ||||
if (sc->qfullmsk == 0 && | if (sc->qfullmsk == 0) | ||||
(ifp->if_drv_flags & IFF_DRV_OACTIVE)) { | iwn_start_locked(sc); | ||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | |||||
iwn_start_locked(ifp); | |||||
} | |||||
} | } | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); | ||||
Context not available. | |||||
iwn_notif_intr(struct iwn_softc *sc) | iwn_notif_intr(struct iwn_softc *sc) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
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); | ||||
uint16_t hw; | uint16_t hw; | ||||
Context not available. | |||||
static void | static void | ||||
iwn_rftoggle_intr(struct iwn_softc *sc) | iwn_rftoggle_intr(struct iwn_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL); | uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL); | ||||
IWN_LOCK_ASSERT(sc); | IWN_LOCK_ASSERT(sc); | ||||
Context not available. | |||||
iwn_intr(void *arg) | iwn_intr(void *arg) | ||||
{ | { | ||||
struct iwn_softc *sc = arg; | struct iwn_softc *sc = arg; | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
uint32_t r1, r2, tmp; | uint32_t r1, r2, tmp; | ||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
Context not available. | |||||
done: | done: | ||||
/* Re-enable interrupts. */ | /* Re-enable interrupts. */ | ||||
if (ifp->if_flags & IFF_UP) | if (sc->sc_flags & IWN_FLAG_RUNNING) | ||||
IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask); | IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask); | ||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
Context not available. | |||||
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) | struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
// struct ifnet *ifp = sc->sc_ifp; | |||||
struct ieee80211vap *vap = ni->ni_vap; | struct ieee80211vap *vap = ni->ni_vap; | ||||
// struct ieee80211com *ic = ifp->if_l2com; | |||||
struct iwn_tx_cmd *cmd; | struct iwn_tx_cmd *cmd; | ||||
struct iwn_cmd_data *tx; | struct iwn_cmd_data *tx; | ||||
struct ieee80211_frame *wh; | struct ieee80211_frame *wh; | ||||
Context not available. | |||||
iwn_xmit_task(void *arg0, int pending) | iwn_xmit_task(void *arg0, int pending) | ||||
{ | { | ||||
struct iwn_softc *sc = arg0; | struct iwn_softc *sc = arg0; | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct ieee80211_node *ni; | struct ieee80211_node *ni; | ||||
struct mbuf *m; | struct mbuf *m; | ||||
int error; | int error; | ||||
Context not available. | |||||
error = iwn_tx_data(sc, m, ni); | error = iwn_tx_data(sc, m, ni); | ||||
if (error != 0) { | if (error != 0) { | ||||
if_inc_counter(ni->ni_vap->iv_ifp, | |||||
IFCOUNTER_OERRORS, 1); | |||||
ieee80211_free_node(ni); | ieee80211_free_node(ni); | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||
} | } | ||||
} | } | ||||
Context not available. | |||||
const struct ieee80211_bpf_params *params) | const struct ieee80211_bpf_params *params) | ||||
{ | { | ||||
struct ieee80211com *ic = ni->ni_ic; | struct ieee80211com *ic = ni->ni_ic; | ||||
struct ifnet *ifp = ic->ic_ifp; | struct iwn_softc *sc = ic->ic_softc; | ||||
struct iwn_softc *sc = ifp->if_softc; | |||||
int error = 0; | int error = 0; | ||||
DPRINTF(sc, IWN_DEBUG_XMIT | IWN_DEBUG_TRACE, "->%s begin\n", __func__); | DPRINTF(sc, IWN_DEBUG_XMIT | IWN_DEBUG_TRACE, "->%s begin\n", __func__); | ||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { | if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) { | ||||
ieee80211_free_node(ni); | ieee80211_free_node(ni); | ||||
m_freem(m); | m_freem(m); | ||||
return ENETDOWN; | return ENETDOWN; | ||||
Context not available. | |||||
if (sc->sc_beacon_wait) { | if (sc->sc_beacon_wait) { | ||||
if (iwn_xmit_queue_enqueue(sc, m) != 0) { | if (iwn_xmit_queue_enqueue(sc, m) != 0) { | ||||
m_freem(m); | m_freem(m); | ||||
if_inc_counter(ni->ni_vap->iv_ifp, | |||||
IFCOUNTER_OERRORS, 1); | |||||
ieee80211_free_node(ni); | ieee80211_free_node(ni); | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
return (ENOBUFS); | return (ENOBUFS); | ||||
} | } | ||||
Context not available. | |||||
if (error != 0) { | if (error != 0) { | ||||
/* NB: m is reclaimed on tx failure */ | /* NB: m is reclaimed on tx failure */ | ||||
ieee80211_free_node(ni); | ieee80211_free_node(ni); | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||
} else | } else | ||||
sc->sc_tx_timer = 5; | sc->sc_tx_timer = 5; | ||||
Context not available. | |||||
return error; | return error; | ||||
} | } | ||||
static void | static int | ||||
iwn_start(struct ifnet *ifp) | iwn_transmit(struct ieee80211com *ic, struct mbuf *m) | ||||
{ | { | ||||
struct iwn_softc *sc = ifp->if_softc; | struct iwn_softc *sc; | ||||
int error; | |||||
sc = ic->ic_softc; | |||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
iwn_start_locked(ifp); | if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) { | ||||
IWN_UNLOCK(sc); | |||||
return (ENXIO); | |||||
} | |||||
error = mbufq_enqueue(&sc->sc_snd, m); | |||||
if (error) { | |||||
IWN_UNLOCK(sc); | |||||
return (error); | |||||
} | |||||
iwn_start_locked(sc); | |||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
return (0); | |||||
} | } | ||||
static void | static void | ||||
iwn_start_locked(struct ifnet *ifp) | iwn_start_locked(struct iwn_softc *sc) | ||||
{ | { | ||||
struct iwn_softc *sc = ifp->if_softc; | |||||
struct ieee80211_node *ni; | struct ieee80211_node *ni; | ||||
struct mbuf *m; | struct mbuf *m; | ||||
Context not available. | |||||
} | } | ||||
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: called\n", __func__); | DPRINTF(sc, IWN_DEBUG_XMIT, "%s: called\n", __func__); | ||||
while (sc->qfullmsk == 0 && | |||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || | (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { | ||||
(ifp->if_drv_flags & IFF_DRV_OACTIVE)) | |||||
return; | |||||
for (;;) { | |||||
if (sc->qfullmsk != 0) { | |||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE; | |||||
break; | |||||
} | |||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m); | |||||
if (m == NULL) | |||||
break; | |||||
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; | ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; | ||||
if (iwn_tx_data(sc, m, ni) != 0) { | if (iwn_tx_data(sc, m, ni) != 0) { | ||||
if_inc_counter(ni->ni_vap->iv_ifp, | |||||
IFCOUNTER_OERRORS, 1); | |||||
ieee80211_free_node(ni); | ieee80211_free_node(ni); | ||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||
} else | } else | ||||
sc->sc_tx_timer = 5; | sc->sc_tx_timer = 5; | ||||
} | } | ||||
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: done\n", __func__); | DPRINTF(sc, IWN_DEBUG_XMIT, "%s: done\n", __func__); | ||||
} | } | ||||
Context not available. | |||||
iwn_watchdog(void *arg) | iwn_watchdog(void *arg) | ||||
{ | { | ||||
struct iwn_softc *sc = arg; | struct iwn_softc *sc = arg; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
IWN_LOCK_ASSERT(sc); | IWN_LOCK_ASSERT(sc); | ||||
KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); | KASSERT(sc->sc_flags & IWN_FLAG_RUNNING, ("not running")); | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | ||||
Context not available. | |||||
} | } | ||||
static int | static int | ||||
iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | iwn_ioctl(struct ieee80211com *ic, u_long cmd, void *data) | ||||
{ | { | ||||
struct iwn_softc *sc = ifp->if_softc; | struct ifreq *ifr = data; | ||||
struct ieee80211com *ic = ifp->if_l2com; | struct iwn_softc *sc = ic->ic_softc; | ||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); | int error = 0; | ||||
struct ifreq *ifr = (struct ifreq *) data; | |||||
int error = 0, startall = 0, stop = 0; | |||||
switch (cmd) { | switch (cmd) { | ||||
case SIOCGIFADDR: | |||||
error = ether_ioctl(ifp, cmd, data); | |||||
break; | |||||
case SIOCSIFFLAGS: | |||||
IWN_LOCK(sc); | |||||
if (ifp->if_flags & IFF_UP) { | |||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { | |||||
iwn_init_locked(sc); | |||||
if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL) | |||||
startall = 1; | |||||
else | |||||
stop = 1; | |||||
} | |||||
} else { | |||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) | |||||
iwn_stop_locked(sc); | |||||
} | |||||
IWN_UNLOCK(sc); | |||||
if (startall) | |||||
ieee80211_start_all(ic); | |||||
else if (vap != NULL && stop) | |||||
ieee80211_stop(vap); | |||||
break; | |||||
case SIOCGIFMEDIA: | |||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); | |||||
break; | |||||
case SIOCGIWNSTATS: | case SIOCGIWNSTATS: | ||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
/* XXX validate permissions/memory/etc? */ | /* XXX validate permissions/memory/etc? */ | ||||
Context not available. | |||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
break; | break; | ||||
default: | default: | ||||
error = EINVAL; | error = ENOTTY; | ||||
break; | break; | ||||
} | } | ||||
return error; | return (error); | ||||
} | } | ||||
static void | |||||
iwn_parent(struct ieee80211com *ic) | |||||
{ | |||||
struct iwn_softc *sc = ic->ic_softc; | |||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); | |||||
int startall = 0, stop = 0; | |||||
IWN_LOCK(sc); | |||||
if (ic->ic_nrunning > 0) { | |||||
if (!(sc->sc_flags & IWN_FLAG_RUNNING)) { | |||||
iwn_init_locked(sc); | |||||
if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL) | |||||
startall = 1; | |||||
else | |||||
stop = 1; | |||||
} | |||||
} else if (sc->sc_flags & IWN_FLAG_RUNNING) | |||||
iwn_stop_locked(sc); | |||||
IWN_UNLOCK(sc); | |||||
if (startall) | |||||
ieee80211_start_all(ic); | |||||
else if (vap != NULL && stop) | |||||
ieee80211_stop(vap); | |||||
} | |||||
/* | /* | ||||
* Send a command to the firmware. | * Send a command to the firmware. | ||||
*/ | */ | ||||
Context not available. | |||||
iwn_add_broadcast_node(struct iwn_softc *sc, int async) | iwn_add_broadcast_node(struct iwn_softc *sc, int async) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct iwn_node_info node; | struct iwn_node_info node; | ||||
struct iwn_cmd_link_quality linkq; | struct iwn_cmd_link_quality linkq; | ||||
uint8_t txant; | uint8_t txant; | ||||
Context not available. | |||||
sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX]; | sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX]; | ||||
memset(&node, 0, sizeof node); | memset(&node, 0, sizeof node); | ||||
IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr); | IEEE80211_ADDR_COPY(node.macaddr, ieee80211broadcastaddr); | ||||
node.id = sc->broadcast_id; | node.id = sc->broadcast_id; | ||||
DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__); | DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__); | ||||
if ((error = ops->add_node(sc, &node, async)) != 0) | if ((error = ops->add_node(sc, &node, async)) != 0) | ||||
Context not available. | |||||
static void | static void | ||||
iwn4965_power_calibration(struct iwn_softc *sc, int temp) | iwn4965_power_calibration(struct iwn_softc *sc, int temp) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | ||||
Context not available. | |||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
struct iwn_calib_state *calib = &sc->calib; | struct iwn_calib_state *calib = &sc->calib; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
uint32_t val; | uint32_t val; | ||||
int i; | int i; | ||||
Context not available. | |||||
static uint32_t | static uint32_t | ||||
iwn_get_rxon_ht_flags(struct iwn_softc *sc, struct ieee80211_channel *c) | iwn_get_rxon_ht_flags(struct iwn_softc *sc, struct ieee80211_channel *c) | ||||
{ | { | ||||
struct ieee80211com *ic = &sc->sc_ic; | |||||
uint32_t htflags = 0; | uint32_t htflags = 0; | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
if (! IEEE80211_IS_CHAN_HT(c)) | if (! IEEE80211_IS_CHAN_HT(c)) | ||||
return (0); | return (0); | ||||
Context not available. | |||||
iwn_config(struct iwn_softc *sc) | iwn_config(struct iwn_softc *sc) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
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); | ||||
const uint8_t *macaddr; | |||||
uint32_t txmask; | uint32_t txmask; | ||||
uint16_t rxchain; | uint16_t rxchain; | ||||
int error; | int error; | ||||
Context not available. | |||||
/* Set mode, channel, RX filter and enable RX. */ | /* Set mode, channel, RX filter and enable RX. */ | ||||
sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX]; | sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX]; | ||||
memset(sc->rxon, 0, sizeof (struct iwn_rxon)); | memset(sc->rxon, 0, sizeof (struct iwn_rxon)); | ||||
IEEE80211_ADDR_COPY(sc->rxon->myaddr, IF_LLADDR(ifp)); | macaddr = vap ? vap->iv_myaddr : ic->ic_macaddr; | ||||
IEEE80211_ADDR_COPY(sc->rxon->wlap, IF_LLADDR(ifp)); | IEEE80211_ADDR_COPY(sc->rxon->myaddr, macaddr); | ||||
IEEE80211_ADDR_COPY(sc->rxon->wlap, macaddr); | |||||
sc->rxon->chan = ieee80211_chan2ieee(ic, ic->ic_curchan); | sc->rxon->chan = ieee80211_chan2ieee(ic, ic->ic_curchan); | ||||
sc->rxon->flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF); | sc->rxon->flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF); | ||||
if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) | if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) | ||||
Context not available. | |||||
static uint16_t | static uint16_t | ||||
iwn_limit_dwell(struct iwn_softc *sc, uint16_t dwell_time) | iwn_limit_dwell(struct iwn_softc *sc, uint16_t dwell_time) | ||||
{ | { | ||||
struct ieee80211com *ic = sc->sc_ifp->if_l2com; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211vap *vap = NULL; | struct ieee80211vap *vap = NULL; | ||||
int bintval = 0; | int bintval = 0; | ||||
Context not available. | |||||
iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap, | iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap, | ||||
struct ieee80211_scan_state *ss, struct ieee80211_channel *c) | struct ieee80211_scan_state *ss, struct ieee80211_channel *c) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct ieee80211_node *ni = vap->iv_bss; | struct ieee80211_node *ni = vap->iv_bss; | ||||
struct iwn_scan_hdr *hdr; | struct iwn_scan_hdr *hdr; | ||||
struct iwn_cmd_data *tx; | struct iwn_cmd_data *tx; | ||||
Context not available. | |||||
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | | wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | | ||||
IEEE80211_FC0_SUBTYPE_PROBE_REQ; | IEEE80211_FC0_SUBTYPE_PROBE_REQ; | ||||
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; | wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; | ||||
IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr); | IEEE80211_ADDR_COPY(wh->i_addr1, vap->iv_ifp->if_broadcastaddr); | ||||
IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp)); | IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(vap->iv_ifp)); | ||||
IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr); | IEEE80211_ADDR_COPY(wh->i_addr3, vap->iv_ifp->if_broadcastaddr); | ||||
*(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */ | *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */ | ||||
*(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */ | *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */ | ||||
Context not available. | |||||
iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap) | iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct ieee80211_node *ni = vap->iv_bss; | struct ieee80211_node *ni = vap->iv_bss; | ||||
int error; | int error; | ||||
Context not available. | |||||
iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) | iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) | ||||
{ | { | ||||
struct iwn_ops *ops = &sc->ops; | struct iwn_ops *ops = &sc->ops; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
struct ieee80211_node *ni = vap->iv_bss; | struct ieee80211_node *ni = vap->iv_bss; | ||||
struct iwn_node_info node; | struct iwn_node_info node; | ||||
int error; | int error; | ||||
Context not available. | |||||
iwn_radio_on(void *arg0, int pending) | iwn_radio_on(void *arg0, int pending) | ||||
{ | { | ||||
struct iwn_softc *sc = arg0; | struct iwn_softc *sc = arg0; | ||||
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); | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | ||||
Context not available. | |||||
iwn_radio_off(void *arg0, int pending) | iwn_radio_off(void *arg0, int pending) | ||||
{ | { | ||||
struct iwn_softc *sc = arg0; | struct iwn_softc *sc = arg0; | ||||
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); | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | ||||
Context not available. | |||||
iwn_panicked(void *arg0, int pending) | iwn_panicked(void *arg0, int pending) | ||||
{ | { | ||||
struct iwn_softc *sc = arg0; | struct iwn_softc *sc = arg0; | ||||
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); | ||||
int error; | int error; | ||||
Context not available. | |||||
} | } | ||||
/* Only run start once the NIC is in a useful state, like associated */ | /* Only run start once the NIC is in a useful state, like associated */ | ||||
iwn_start_locked(sc->sc_ifp); | iwn_start_locked(sc); | ||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
} | } | ||||
Context not available. | |||||
static void | static void | ||||
iwn_init_locked(struct iwn_softc *sc) | iwn_init_locked(struct iwn_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
int error; | int error; | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); | ||||
Context not available. | |||||
IWN_LOCK_ASSERT(sc); | IWN_LOCK_ASSERT(sc); | ||||
sc->sc_flags |= IWN_FLAG_RUNNING; | |||||
if ((error = iwn_hw_prepare(sc)) != 0) { | if ((error = iwn_hw_prepare(sc)) != 0) { | ||||
device_printf(sc->sc_dev, "%s: hardware not ready, error %d\n", | device_printf(sc->sc_dev, "%s: hardware not ready, error %d\n", | ||||
__func__, error); | __func__, error); | ||||
Context not available. | |||||
goto fail; | goto fail; | ||||
} | } | ||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | |||||
ifp->if_drv_flags |= IFF_DRV_RUNNING; | |||||
callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); | callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); | ||||
Context not available. | |||||
return; | return; | ||||
fail: iwn_stop_locked(sc); | fail: | ||||
sc->sc_flags &= ~IWN_FLAG_RUNNING; | |||||
iwn_stop_locked(sc); | |||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end in error\n",__func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end in error\n",__func__); | ||||
} | } | ||||
static void | static void | ||||
iwn_init(void *arg) | iwn_init(struct iwn_softc *sc) | ||||
{ | { | ||||
struct iwn_softc *sc = arg; | |||||
struct ifnet *ifp = sc->sc_ifp; | |||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
iwn_init_locked(sc); | iwn_init_locked(sc); | ||||
IWN_UNLOCK(sc); | IWN_UNLOCK(sc); | ||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) | if (sc->sc_flags & IWN_FLAG_RUNNING) | ||||
ieee80211_start_all(ic); | ieee80211_start_all(&sc->sc_ic); | ||||
} | } | ||||
static void | static void | ||||
iwn_stop_locked(struct iwn_softc *sc) | iwn_stop_locked(struct iwn_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | |||||
IWN_LOCK_ASSERT(sc); | IWN_LOCK_ASSERT(sc); | ||||
Context not available. | |||||
sc->sc_tx_timer = 0; | sc->sc_tx_timer = 0; | ||||
callout_stop(&sc->watchdog_to); | callout_stop(&sc->watchdog_to); | ||||
callout_stop(&sc->calib_to); | callout_stop(&sc->calib_to); | ||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); | sc->sc_flags &= ~IWN_FLAG_RUNNING; | ||||
/* Power OFF hardware. */ | /* Power OFF hardware. */ | ||||
iwn_hw_stop(sc); | iwn_hw_stop(sc); | ||||
Context not available. | |||||
static void | static void | ||||
iwn_scan_start(struct ieee80211com *ic) | iwn_scan_start(struct ieee80211com *ic) | ||||
{ | { | ||||
struct ifnet *ifp = ic->ic_ifp; | struct iwn_softc *sc = ic->ic_softc; | ||||
struct iwn_softc *sc = ifp->if_softc; | |||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
/* make the link LED blink while we're scanning */ | /* make the link LED blink while we're scanning */ | ||||
Context not available. | |||||
static void | static void | ||||
iwn_scan_end(struct ieee80211com *ic) | iwn_scan_end(struct ieee80211com *ic) | ||||
{ | { | ||||
struct ifnet *ifp = ic->ic_ifp; | struct iwn_softc *sc = ic->ic_softc; | ||||
struct iwn_softc *sc = ifp->if_softc; | |||||
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); | struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); | ||||
IWN_LOCK(sc); | IWN_LOCK(sc); | ||||
Context not available. | |||||
iwn_set_channel(struct ieee80211com *ic) | iwn_set_channel(struct ieee80211com *ic) | ||||
{ | { | ||||
const struct ieee80211_channel *c = ic->ic_curchan; | const struct ieee80211_channel *c = ic->ic_curchan; | ||||
struct ifnet *ifp = ic->ic_ifp; | struct iwn_softc *sc = ic->ic_softc; | ||||
struct iwn_softc *sc = ifp->if_softc; | |||||
int error; | int error; | ||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | ||||
Context not available. | |||||
iwn_hw_reset(void *arg0, int pending) | iwn_hw_reset(void *arg0, int pending) | ||||
{ | { | ||||
struct iwn_softc *sc = arg0; | struct iwn_softc *sc = arg0; | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ieee80211com *ic = &sc->sc_ic; | ||||
struct ieee80211com *ic = ifp->if_l2com; | |||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); | ||||
Context not available. |