|
|
|
@@ -1,4 +1,6 @@
|
|
|
|
|
/*-
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2004, 2005
|
|
|
|
|
* Damien Bergamini <[email protected]>. All rights reserved.
|
|
|
|
|
* Copyright (c) 2005-2006 Sam Leffler, Errno Consulting
|
|
|
|
@@ -28,7 +30,7 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
|
__FBSDID("$FreeBSD: releng/11.2/sys/dev/iwi/if_iwi.c 332288 2018-04-08 16:54:07Z brooks $");
|
|
|
|
|
__FBSDID("$FreeBSD: releng/12.0/sys/dev/iwi/if_iwi.c 331797 2018-03-30 18:50:13Z brooks $");
|
|
|
|
|
|
|
|
|
|
/*-
|
|
|
|
|
* Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
|
|
|
|
@@ -555,7 +557,7 @@ iwi_alloc_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring, int count)
|
|
|
|
|
|
|
|
|
|
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0,
|
|
|
|
|
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
|
|
|
|
|
count * IWI_CMD_DESC_SIZE, 1, count * IWI_CMD_DESC_SIZE, 0,
|
|
|
|
|
count * IWI_CMD_DESC_SIZE, 1, count * IWI_CMD_DESC_SIZE, 0,
|
|
|
|
|
NULL, NULL, &ring->desc_dmat);
|
|
|
|
|
if (error != 0) {
|
|
|
|
|
device_printf(sc->sc_dev, "could not create desc DMA tag\n");
|
|
|
|
@@ -600,7 +602,7 @@ iwi_free_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ring->desc_dmat != NULL)
|
|
|
|
|
bus_dma_tag_destroy(ring->desc_dmat);
|
|
|
|
|
bus_dma_tag_destroy(ring->desc_dmat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
@@ -617,7 +619,7 @@ iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count,
|
|
|
|
|
|
|
|
|
|
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0,
|
|
|
|
|
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
|
|
|
|
|
count * IWI_TX_DESC_SIZE, 1, count * IWI_TX_DESC_SIZE, 0, NULL,
|
|
|
|
|
count * IWI_TX_DESC_SIZE, 1, count * IWI_TX_DESC_SIZE, 0, NULL,
|
|
|
|
|
NULL, &ring->desc_dmat);
|
|
|
|
|
if (error != 0) {
|
|
|
|
|
device_printf(sc->sc_dev, "could not create desc DMA tag\n");
|
|
|
|
@@ -894,7 +896,7 @@ iwi_node_free(struct ieee80211_node *ni)
|
|
|
|
|
sc->sc_node_free(ni);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
/*
|
|
|
|
|
* Convert h/w rate code to IEEE rate code.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
@@ -1048,12 +1050,15 @@ static int
|
|
|
|
|
iwi_wme_setparams(struct iwi_softc *sc)
|
|
|
|
|
{
|
|
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
|
|
|
|
struct chanAccParams chp;
|
|
|
|
|
const struct wmeParams *wmep;
|
|
|
|
|
int ac;
|
|
|
|
|
|
|
|
|
|
ieee80211_wme_ic_getparams(ic, &chp);
|
|
|
|
|
|
|
|
|
|
for (ac = 0; ac < WME_NUM_AC; ac++) {
|
|
|
|
|
/* set WME values for current operating mode */
|
|
|
|
|
wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
|
|
|
|
|
wmep = &chp.cap_wmeParams[ac];
|
|
|
|
|
sc->wme[0].aifsn[ac] = wmep->wmep_aifsn;
|
|
|
|
|
sc->wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
|
|
|
|
|
sc->wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
|
|
|
|
@@ -1773,11 +1778,9 @@ iwi_tx_start(struct iwi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
|
|
|
|
int ac)
|
|
|
|
|
{
|
|
|
|
|
struct ieee80211vap *vap = ni->ni_vap;
|
|
|
|
|
struct ieee80211com *ic = ni->ni_ic;
|
|
|
|
|
struct iwi_node *in = (struct iwi_node *)ni;
|
|
|
|
|
const struct ieee80211_frame *wh;
|
|
|
|
|
struct ieee80211_key *k;
|
|
|
|
|
const struct chanAccParams *cap;
|
|
|
|
|
struct iwi_tx_ring *txq = &sc->txq[ac];
|
|
|
|
|
struct iwi_tx_data *data;
|
|
|
|
|
struct iwi_tx_desc *desc;
|
|
|
|
@@ -1799,8 +1802,7 @@ iwi_tx_start(struct iwi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
|
|
|
|
flags |= IWI_DATA_FLAG_SHPREAMBLE;
|
|
|
|
|
if (IEEE80211_QOS_HAS_SEQ(wh)) {
|
|
|
|
|
xflags |= IWI_DATA_XFLAG_QOS;
|
|
|
|
|
cap = &ic->ic_wme.wme_chanParams;
|
|
|
|
|
if (!cap->cap_wmeParams[ac].wmep_noackPolicy)
|
|
|
|
|
if (ieee80211_wme_vap_ac_is_noack(vap, ac))
|
|
|
|
|
flags &= ~IWI_DATA_FLAG_NEED_ACK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2553,12 +2555,36 @@ iwi_setwepkeys(struct iwi_softc *sc, struct ieee80211vap *vap)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
iwi_set_rateset(struct iwi_softc *sc, const struct ieee80211_rateset *net_rs,
|
|
|
|
|
int mode, int type)
|
|
|
|
|
{
|
|
|
|
|
struct iwi_rateset rs;
|
|
|
|
|
|
|
|
|
|
memset(&rs, 0, sizeof(rs));
|
|
|
|
|
rs.mode = mode;
|
|
|
|
|
rs.type = type;
|
|
|
|
|
rs.nrates = net_rs->rs_nrates;
|
|
|
|
|
if (rs.nrates > nitems(rs.rates)) {
|
|
|
|
|
DPRINTF(("Truncating negotiated rate set from %u\n",
|
|
|
|
|
rs.nrates));
|
|
|
|
|
rs.nrates = nitems(rs.rates);
|
|
|
|
|
}
|
|
|
|
|
memcpy(rs.rates, net_rs->rs_rates, rs.nrates);
|
|
|
|
|
DPRINTF(("Setting .11%c%s %s rates (%u)\n",
|
|
|
|
|
mode == IWI_MODE_11A ? 'a' : 'b',
|
|
|
|
|
mode == IWI_MODE_11G ? "g" : "",
|
|
|
|
|
type == IWI_RATESET_TYPE_SUPPORTED ? "supported" : "negotiated",
|
|
|
|
|
rs.nrates));
|
|
|
|
|
|
|
|
|
|
return (iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof(rs)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
iwi_config(struct iwi_softc *sc)
|
|
|
|
|
{
|
|
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
|
|
|
|
struct iwi_configuration config;
|
|
|
|
|
struct iwi_rateset rs;
|
|
|
|
|
struct iwi_txpower power;
|
|
|
|
|
uint32_t data;
|
|
|
|
|
int error, i;
|
|
|
|
@@ -2607,25 +2633,13 @@ iwi_config(struct iwi_softc *sc)
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(&rs, 0, sizeof rs);
|
|
|
|
|
rs.mode = IWI_MODE_11G;
|
|
|
|
|
rs.type = IWI_RATESET_TYPE_SUPPORTED;
|
|
|
|
|
rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates;
|
|
|
|
|
memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11G].rs_rates,
|
|
|
|
|
rs.nrates);
|
|
|
|
|
DPRINTF(("Setting .11bg supported rates (%u)\n", rs.nrates));
|
|
|
|
|
error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs);
|
|
|
|
|
error = iwi_set_rateset(sc, &ic->ic_sup_rates[IEEE80211_MODE_11G],
|
|
|
|
|
IWI_MODE_11G, IWI_RATESET_TYPE_SUPPORTED);
|
|
|
|
|
if (error != 0)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
memset(&rs, 0, sizeof rs);
|
|
|
|
|
rs.mode = IWI_MODE_11A;
|
|
|
|
|
rs.type = IWI_RATESET_TYPE_SUPPORTED;
|
|
|
|
|
rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates;
|
|
|
|
|
memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11A].rs_rates,
|
|
|
|
|
rs.nrates);
|
|
|
|
|
DPRINTF(("Setting .11a supported rates (%u)\n", rs.nrates));
|
|
|
|
|
error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs);
|
|
|
|
|
error = iwi_set_rateset(sc, &ic->ic_sup_rates[IEEE80211_MODE_11A],
|
|
|
|
|
IWI_MODE_11A, IWI_RATESET_TYPE_SUPPORTED);
|
|
|
|
|
if (error != 0)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
@@ -2819,7 +2833,6 @@ iwi_auth_and_assoc(struct iwi_softc *sc, struct ieee80211vap *vap)
|
|
|
|
|
struct ieee80211_node *ni;
|
|
|
|
|
struct iwi_configuration config;
|
|
|
|
|
struct iwi_associate *assoc = &sc->assoc;
|
|
|
|
|
struct iwi_rateset rs;
|
|
|
|
|
uint16_t capinfo;
|
|
|
|
|
uint32_t data;
|
|
|
|
|
int error, mode;
|
|
|
|
@@ -2889,18 +2902,8 @@ iwi_auth_and_assoc(struct iwi_softc *sc, struct ieee80211vap *vap)
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
|
|
/* the rate set has already been "negotiated" */
|
|
|
|
|
memset(&rs, 0, sizeof rs);
|
|
|
|
|
rs.mode = mode;
|
|
|
|
|
rs.type = IWI_RATESET_TYPE_NEGOTIATED;
|
|
|
|
|
rs.nrates = ni->ni_rates.rs_nrates;
|
|
|
|
|
if (rs.nrates > IWI_RATESET_SIZE) {
|
|
|
|
|
DPRINTF(("Truncating negotiated rate set from %u\n",
|
|
|
|
|
rs.nrates));
|
|
|
|
|
rs.nrates = IWI_RATESET_SIZE;
|
|
|
|
|
}
|
|
|
|
|
memcpy(rs.rates, ni->ni_rates.rs_rates, rs.nrates);
|
|
|
|
|
DPRINTF(("Setting negotiated rates (%u)\n", rs.nrates));
|
|
|
|
|
error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs);
|
|
|
|
|
error = iwi_set_rateset(sc, &ni->ni_rates, mode,
|
|
|
|
|
IWI_RATESET_TYPE_NEGOTIATED);
|
|
|
|
|
if (error != 0)
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
|
@@ -2940,7 +2943,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc, struct ieee80211vap *vap)
|
|
|
|
|
* key setup. This typically is due to a user app bug
|
|
|
|
|
* but if we blindly grab the key the firmware will
|
|
|
|
|
* barf so avoid it for now.
|
|
|
|
|
*/
|
|
|
|
|
*/
|
|
|
|
|
if (vap->iv_def_txkey != IEEE80211_KEYIX_NONE)
|
|
|
|
|
assoc->auth |= vap->iv_def_txkey << 4;
|
|
|
|
|
|
|
|
|
|