PERFORCE change 83716 for review
Sam Leffler
sam at FreeBSD.org
Thu Sep 15 15:51:54 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=83716
Change 83716 by sam at sam_ebb on 2005/09/15 22:51:17
checkpoint driver conversion
Affected files ...
.. //depot/projects/wifi/sys/dev/ipw/if_ipw.c#6 edit
.. //depot/projects/wifi/sys/dev/iwi/if_iwi.c#8 edit
.. //depot/projects/wifi/sys/dev/ral/if_ral.c#5 edit
.. //depot/projects/wifi/sys/dev/ral/if_ralvar.h#3 edit
.. //depot/projects/wifi/sys/dev/usb/if_ural.c#5 edit
.. //depot/projects/wifi/sys/dev/usb/if_uralvar.h#3 edit
.. //depot/projects/wifi/sys/dev/wi/if_wi.c#18 edit
Differences ...
==== //depot/projects/wifi/sys/dev/ipw/if_ipw.c#6 (text+ko) ====
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.7 2005/07/08 19:30:29 damien Exp $ */
+/* $FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.13 2005/08/20 15:03:41 damien Exp $ */
/*-
* Copyright (c) 2004, 2005
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.7 2005/07/08 19:30:29 damien Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.13 2005/08/20 15:03:41 damien Exp $");
/*-
* Intel(R) PRO/Wireless 2100 MiniPCI driver
@@ -130,9 +130,7 @@
static int ipw_config(struct ipw_softc *);
static void ipw_init(void *);
static void ipw_stop(void *);
-#ifdef IPW_DEBUG
static int ipw_sysctl_stats(SYSCTL_HANDLER_ARGS);
-#endif
static int ipw_sysctl_radio(SYSCTL_HANDLER_ARGS);
static uint32_t ipw_read_table1(struct ipw_softc *, uint32_t);
static void ipw_write_table1(struct ipw_softc *, uint32_t, uint32_t);
@@ -289,8 +287,7 @@
/* set device capabilities */
ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT |
- IEEE80211_C_PMGT | IEEE80211_C_IBSS | IEEE80211_C_MONITOR |
- IEEE80211_C_WPA;
+ IEEE80211_C_PMGT | IEEE80211_C_IBSS | IEEE80211_C_MONITOR;
/* read MAC address from EEPROM */
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0);
@@ -350,12 +347,10 @@
CTLTYPE_INT | CTLFLAG_RD, sc, 0, ipw_sysctl_radio, "I",
"radio transmitter switch state (0=off, 1=on)");
-#ifdef IPW_DEBUG
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats",
CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, ipw_sysctl_stats, "S",
"statistics");
-#endif
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell",
@@ -735,7 +730,7 @@
if (ifp->if_flags & IFF_UP) {
ifp->if_init(ifp->if_softc);
- if (ifp->if_flags & IFF_RUNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ifp->if_start(ifp);
}
@@ -758,7 +753,7 @@
return error;
}
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
+ if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
ipw_init(sc);
IPW_UNLOCK(sc);
@@ -828,7 +823,6 @@
{
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
uint8_t macaddr[IEEE80211_ADDR_LEN];
uint32_t len;
@@ -839,16 +833,18 @@
len = IEEE80211_ADDR_LEN;
ipw_read_table2(sc, IPW_INFO_CURRENT_BSSID, macaddr, &len);
+#if 0
ni = ieee80211_find_node(&ic->ic_scan, macaddr);
if (ni == NULL)
break;
ieee80211_ref_node(ni);
ieee80211_sta_join(ic, ni);
- ieee80211_node_authorize(ic, ni);
+ ieee80211_node_authorize(ni);
if (ic->ic_opmode == IEEE80211_M_STA)
ieee80211_notify_node_join(ic, ni, 1);
+#endif
break;
case IEEE80211_S_INIT:
@@ -1204,7 +1200,7 @@
/* remember what the firmware has processed */
sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1;
- ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
ipw_start(ifp);
}
@@ -1480,7 +1476,7 @@
if (sc->txfree < 1 + IPW_MAX_NSEG) {
IFQ_DRV_PREPEND(&ifp->if_snd, m0);
- ifp->if_flags |= IFF_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
@@ -1523,7 +1519,6 @@
ipw_watchdog(struct ifnet *ifp)
{
struct ipw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = &sc->sc_ic;
ifp->if_timer = 0;
@@ -1537,8 +1532,6 @@
}
ifp->if_timer = 1;
}
-
- ieee80211_watchdog(ic);
}
static int
@@ -1554,10 +1547,10 @@
switch (cmd) {
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_flags & IFF_RUNNING))
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
ipw_init(sc);
} else {
- if (ifp->if_flags & IFF_RUNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ipw_stop(sc);
}
break;
@@ -1586,8 +1579,8 @@
}
if (error == ENETRESET) {
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
- (IFF_UP | IFF_RUNNING))
+ if ((ifp->if_flags & IFF_UP) &&
+ (ifp->if_drv_flags & IFF_DRV_RUNNING))
ipw_init(sc);
error = 0;
}
@@ -1933,8 +1926,8 @@
printf("\n");
}
#endif
- error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_essid,
- ic->ic_des_esslen);
+ error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_ssid[0].ssid,
+ ic->ic_des_ssid[0].len);
if (error != 0)
return error;
@@ -2007,7 +2000,7 @@
#endif
if (ic->ic_opmode == IEEE80211_M_IBSS) {
- data = htole32(ic->ic_lintval);
+ data = htole32(ic->ic_bintval);
DPRINTF(("Setting beacon interval to %u\n", le32toh(data)));
error = ipw_cmd(sc, IPW_CMD_SET_BEACON_INTERVAL, &data,
sizeof data);
@@ -2096,8 +2089,8 @@
goto fail;
}
- ifp->if_flags &= ~IFF_OACTIVE;
- ifp->if_flags |= IFF_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
return;
@@ -2125,12 +2118,11 @@
sc->sc_tx_timer = 0;
ifp->if_timer = 0;
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
}
-#ifdef IPW_DEBUG
static int
ipw_sysctl_stats(SYSCTL_HANDLER_ARGS)
{
@@ -2150,7 +2142,6 @@
return SYSCTL_OUT(req, buf, sizeof buf);
}
-#endif
static int
ipw_sysctl_radio(SYSCTL_HANDLER_ARGS)
==== //depot/projects/wifi/sys/dev/iwi/if_iwi.c#8 (text+ko) ====
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.8 2005/07/10 00:17:04 sam Exp $ */
+/* $FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 damien Exp $ */
/*-
* Copyright (c) 2004, 2005
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.8 2005/07/10 00:17:04 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 damien Exp $");
/*-
* Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
@@ -109,7 +109,7 @@
static void iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
static void iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
static int iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *,
- int);
+ int, bus_addr_t, bus_addr_t);
static void iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
static void iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
static int iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *,
@@ -119,13 +119,14 @@
static int iwi_media_change(struct ifnet *);
static void iwi_media_status(struct ifnet *, struct ifmediareq *);
static int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
+static int iwi_wme_update(struct ieee80211com *);
static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t);
static void iwi_fix_channel(struct ieee80211com *, struct mbuf *);
static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
struct iwi_frame *);
static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
static void iwi_rx_intr(struct iwi_softc *);
-static void iwi_tx_intr(struct iwi_softc *);
+static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
static void iwi_intr(void *);
static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int);
static int iwi_tx_start(struct ifnet *, struct mbuf *,
@@ -145,9 +146,7 @@
static int iwi_auth_and_assoc(struct iwi_softc *);
static void iwi_init(void *);
static void iwi_stop(void *);
-#ifdef IWI_DEBUG
static int iwi_sysctl_stats(SYSCTL_HANDLER_ARGS);
-#endif
static int iwi_sysctl_radio(SYSCTL_HANDLER_ARGS);
static int iwi_probe(device_t);
@@ -281,8 +280,31 @@
goto fail;
}
- if (iwi_alloc_tx_ring(sc, &sc->txq, IWI_TX_RING_COUNT) != 0) {
- device_printf(dev, "could not allocate Tx ring\n");
+ error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_TX_RING_COUNT,
+ IWI_CSR_TX1_RIDX, IWI_CSR_TX1_WIDX);
+ if (error != 0) {
+ device_printf(dev, "could not allocate Tx ring 1\n");
+ goto fail;
+ }
+
+ error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_TX_RING_COUNT,
+ IWI_CSR_TX2_RIDX, IWI_CSR_TX2_WIDX);
+ if (error != 0) {
+ device_printf(dev, "could not allocate Tx ring 2\n");
+ goto fail;
+ }
+
+ error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_TX_RING_COUNT,
+ IWI_CSR_TX3_RIDX, IWI_CSR_TX3_WIDX);
+ if (error != 0) {
+ device_printf(dev, "could not allocate Tx ring 3\n");
+ goto fail;
+ }
+
+ error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_TX_RING_COUNT,
+ IWI_CSR_TX4_RIDX, IWI_CSR_TX4_WIDX);
+ if (error != 0) {
+ device_printf(dev, "could not allocate Tx ring 4\n");
goto fail;
}
@@ -309,13 +331,18 @@
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_wme.wme_update = iwi_wme_update;
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
ic->ic_state = IEEE80211_S_INIT;
/* set device capabilities */
- ic->ic_caps = IEEE80211_C_WPA | IEEE80211_C_PMGT | IEEE80211_C_TXPMGT |
- IEEE80211_C_SHPREAMBLE | IEEE80211_C_MONITOR;
+ ic->ic_caps =
+ IEEE80211_C_MONITOR | /* monitor mode supported */
+ IEEE80211_C_TXPMGT | /* tx power management */
+ IEEE80211_C_SHPREAMBLE | /* short preamble supported */
+ IEEE80211_C_WPA | /* 802.11i */
+ IEEE80211_C_WME; /* 802.11e */
/* read MAC address from EEPROM */
val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
@@ -390,12 +417,10 @@
CTLTYPE_INT | CTLFLAG_RD, sc, 0, iwi_sysctl_radio, "I",
"radio transmitter switch state (0=off, 1=on)");
-#ifdef IWI_DEBUG
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats",
CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, iwi_sysctl_stats, "S",
"statistics");
-#endif
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell",
@@ -447,7 +472,10 @@
if_free(ifp);
iwi_free_cmd_ring(sc, &sc->cmdq);
- iwi_free_tx_ring(sc, &sc->txq);
+ iwi_free_tx_ring(sc, &sc->txq[0]);
+ iwi_free_tx_ring(sc, &sc->txq[1]);
+ iwi_free_tx_ring(sc, &sc->txq[2]);
+ iwi_free_tx_ring(sc, &sc->txq[3]);
iwi_free_rx_ring(sc, &sc->rxq);
if (sc->irq != NULL) {
@@ -533,13 +561,16 @@
}
static int
-iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count)
+iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count,
+ bus_addr_t csr_ridx, bus_addr_t csr_widx)
{
int i, error;
ring->count = count;
ring->queued = 0;
ring->cur = ring->next = 0;
+ ring->csr_ridx = csr_ridx;
+ ring->csr_widx = csr_widx;
error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL, count * IWI_TX_DESC_SIZE, 1,
@@ -788,7 +819,7 @@
if (ifp->if_flags & IFF_UP) {
ifp->if_init(ifp->if_softc);
- if (ifp->if_flags & IFF_RUNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ifp->if_start(ifp);
}
@@ -811,7 +842,7 @@
return error;
}
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
+ if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
iwi_init(sc);
IWI_UNLOCK(sc);
@@ -890,11 +921,15 @@
struct iwi_softc *sc = ifp->if_softc;
switch (nstate) {
+ case IEEE80211_S_INIT:
+ sc->flags &= ~IWI_FLAG_SCANNING;
+ break;
+
case IEEE80211_S_SCAN:
if (sc->flags & IWI_FLAG_SCANNING)
break;
- ieee80211_node_table_reset(&ic->ic_scan);
+ ieee80211_scan_flush(ic);
ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
sc->flags |= IWI_FLAG_SCANNING;
iwi_scan(sc);
@@ -907,17 +942,11 @@
case IEEE80211_S_RUN:
if (ic->ic_opmode == IEEE80211_M_IBSS)
ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
- else if (ic->ic_opmode == IEEE80211_M_MONITOR)
- iwi_set_chan(sc, ic->ic_curchan);
return sc->sc_newstate(ic, nstate,
IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
- case IEEE80211_S_ASSOC:
- break;
-
- case IEEE80211_S_INIT:
- sc->flags &= ~IWI_FLAG_SCANNING;
+ default:
break;
}
@@ -926,6 +955,74 @@
}
/*
+ * WME parameters coming from IEEE 802.11e specification. These values are
+ * already declared in ieee80211_proto.c, but they are static so they can't
+ * be reused here.
+ */
+static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = {
+ { 0, 3, 5, 7, 0 }, /* WME_AC_BE */
+ { 0, 3, 5, 10, 0 }, /* WME_AC_BK */
+ { 0, 2, 4, 5, 188 }, /* WME_AC_VI */
+ { 0, 2, 3, 4, 102 } /* WME_AC_VO */
+};
+
+static const struct wmeParams iwi_wme_ofdm_params[WME_NUM_AC] = {
+ { 0, 3, 4, 6, 0 }, /* WME_AC_BE */
+ { 0, 3, 4, 10, 0 }, /* WME_AC_BK */
+ { 0, 2, 3, 4, 94 }, /* WME_AC_VI */
+ { 0, 2, 2, 3, 47 } /* WME_AC_VO */
+};
+
+static int
+iwi_wme_update(struct ieee80211com *ic)
+{
+#define IWI_EXP2(v) htole16((1 << (v)) - 1)
+#define IWI_USEC(v) htole16(IEEE80211_TXOP_TO_US(v))
+ struct iwi_softc *sc = ic->ic_ifp->if_softc;
+ struct iwi_wme_params wme[3];
+ const struct wmeParams *wmep;
+ int ac;
+
+ /*
+ * We shall not override firmware default WME values if WME is not
+ * actually enabled.
+ */
+ if (!(ic->ic_flags & IEEE80211_F_WME))
+ return 0;
+
+ for (ac = 0; ac < WME_NUM_AC; ac++) {
+ /* set WME values for current operating mode */
+ wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
+ wme[0].aifsn[ac] = wmep->wmep_aifsn;
+ wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+ wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+ wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+ wme[0].acm[ac] = wmep->wmep_acm;
+
+ /* set WME values for CCK modulation */
+ wmep = &iwi_wme_cck_params[ac];
+ wme[1].aifsn[ac] = wmep->wmep_aifsn;
+ wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+ wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+ wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+ wme[1].acm[ac] = wmep->wmep_acm;
+
+ /* set WME values for OFDM modulation */
+ wmep = &iwi_wme_ofdm_params[ac];
+ wme[2].aifsn[ac] = wmep->wmep_aifsn;
+ wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+ wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+ wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+ wme[2].acm[ac] = wmep->wmep_acm;
+ }
+
+ DPRINTF(("Setting WME parameters\n"));
+ return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, wme, sizeof wme, 1);
+#undef IWI_USEC
+#undef IWI_EXP2
+}
+
+/*
* Read 16 bits at address 'addr' from the serial EEPROM.
*/
static uint16_t
@@ -1128,7 +1225,7 @@
switch (auth->state) {
case IWI_AUTHENTICATED:
- ieee80211_node_authorize(ic, ic->ic_bss);
+ ieee80211_node_authorize(ic->ic_bss);
ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
break;
@@ -1157,7 +1254,11 @@
break;
case IWI_DEASSOCIATED:
+#if 0
ieee80211_begin_scan(ic, 1);
+#else
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
+#endif
break;
default:
@@ -1222,36 +1323,36 @@
}
static void
-iwi_tx_intr(struct iwi_softc *sc)
+iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
struct iwi_tx_data *data;
uint32_t hw;
- hw = CSR_READ_4(sc, IWI_CSR_TX1_RIDX);
+ hw = CSR_READ_4(sc, txq->csr_ridx);
- for (; sc->txq.next != hw;) {
- data = &sc->txq.data[sc->txq.next];
+ for (; txq->next != hw;) {
+ data = &txq->data[txq->next];
- bus_dmamap_sync(sc->txq.data_dmat, data->map,
+ bus_dmamap_sync(txq->data_dmat, data->map,
BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->txq.data_dmat, data->map);
+ bus_dmamap_unload(txq->data_dmat, data->map);
m_freem(data->m);
data->m = NULL;
ieee80211_free_node(data->ni);
data->ni = NULL;
- DPRINTFN(15, ("tx done idx=%u\n", sc->txq.next));
+ DPRINTFN(15, ("tx done idx=%u\n", txq->next));
ifp->if_opackets++;
- sc->txq.queued--;
- sc->txq.next = (sc->txq.next + 1) % IWI_TX_RING_COUNT;
+ txq->queued--;
+ txq->next = (txq->next + 1) % IWI_TX_RING_COUNT;
}
sc->sc_tx_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
iwi_start(ifp);
}
@@ -1288,14 +1389,23 @@
iwi_stop(sc);
}
- if (r & IWI_INTR_RX_DONE)
- iwi_rx_intr(sc);
-
if (r & IWI_INTR_CMD_DONE)
wakeup(sc);
if (r & IWI_INTR_TX1_DONE)
- iwi_tx_intr(sc);
+ iwi_tx_intr(sc, &sc->txq[0]);
+
+ if (r & IWI_INTR_TX2_DONE)
+ iwi_tx_intr(sc, &sc->txq[1]);
+
+ if (r & IWI_INTR_TX3_DONE)
+ iwi_tx_intr(sc, &sc->txq[2]);
+
+ if (r & IWI_INTR_TX4_DONE)
+ iwi_tx_intr(sc, &sc->txq[3]);
+
+ if (r & IWI_INTR_RX_DONE)
+ iwi_rx_intr(sc);
/* acknowledge interrupts */
CSR_WRITE_4(sc, IWI_CSR_INTR, r);
@@ -1336,21 +1446,48 @@
{
struct iwi_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- struct ieee80211_frame wh;
+ struct ieee80211_frame *wh;
struct ieee80211_key *k;
+ const struct chanAccParams *cap;
+ struct iwi_tx_ring *txq;
struct iwi_tx_data *data;
struct iwi_tx_desc *desc;
struct mbuf *mnew;
bus_dma_segment_t segs[IWI_MAX_NSEG];
- int nsegs, error, i;
+ int error, nsegs, hdrlen, ac, i, noack = 0;
+
+ wh = mtod(m0, struct ieee80211_frame *);
+
+ if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
+ hdrlen = sizeof (struct ieee80211_qosframe);
+ ac = M_WME_GETAC(m0);
+ cap = &ic->ic_wme.wme_chanParams;
+ noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
+ } else {
+ hdrlen = sizeof (struct ieee80211_frame);
+ ac = WME_AC_BE;
+ }
+
+ txq = &sc->txq[ac];
+ if (txq->queued >= IWI_TX_RING_COUNT - 4) {
+ /*
+ * There is no place left in this ring. Perhaps in 802.11e,
+ * we should try to fallback to a lowest priority ring?
+ */
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ m_freem(m0);
+ return 0;
+ }
- bcopy(mtod(m0, struct ieee80211_frame *), &wh, sizeof (struct ieee80211_frame));
- if (wh.i_fc[1] & IEEE80211_FC1_WEP) {
+ if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
k = ieee80211_crypto_encap(ic, ni, m0);
if (k == NULL) {
m_freem(m0);
return ENOBUFS;
}
+
+ /* packet header may have moved, reset our local pointer */
+ wh = mtod(m0, struct ieee80211_frame *);
}
if (sc->sc_drvbpf != NULL) {
@@ -1363,13 +1500,14 @@
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
}
- data = &sc->txq.data[sc->txq.cur];
- desc = &sc->txq.desc[sc->txq.cur];
+ data = &txq->data[txq->cur];
+ desc = &txq->desc[txq->cur];
- /* trim IEEE802.11 header */
- m_adj(m0, sizeof (struct ieee80211_frame));
+ /* save and trim IEEE802.11 header */
+ m_copydata(m0, 0, hdrlen, (caddr_t)&desc->wh);
+ m_adj(m0, hdrlen);
- error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, m0, segs,
+ error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0, segs,
&nsegs, 0);
if (error != 0 && error != EFBIG) {
device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
@@ -1387,7 +1525,7 @@
}
m0 = mnew;
- error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map,
+ error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map,
m0, segs, &nsegs, 0);
if (error != 0) {
device_printf(sc->sc_dev,
@@ -1404,15 +1542,15 @@
desc->hdr.flags = IWI_HDR_FLAG_IRQ;
desc->cmd = IWI_DATA_CMD_TX;
desc->len = htole16(m0->m_pkthdr.len);
- memcpy(&desc->wh, &wh, sizeof (struct ieee80211_frame));
desc->flags = 0;
+ desc->xflags = 0;
- if (!IEEE80211_IS_MULTICAST(wh.i_addr1))
+ if (!noack && !IEEE80211_IS_MULTICAST(desc->wh.i_addr1))
desc->flags |= IWI_DATA_FLAG_NEED_ACK;
#if 0
if (ic->ic_flags & IEEE80211_F_PRIVACY) {
- wh.i_fc[1] |= IEEE80211_FC1_WEP;
+ desc->wh.i_fc[1] |= IEEE80211_FC1_WEP;
desc->wep_txkey = ic->ic_crypto.cs_def_txkey;
} else
#endif
@@ -1421,22 +1559,24 @@
if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
desc->flags |= IWI_DATA_FLAG_SHPREAMBLE;
+ if (desc->wh.i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)
+ desc->xflags |= IWI_DATA_XFLAG_QOS;
+
desc->nseg = htole32(nsegs);
for (i = 0; i < nsegs; i++) {
desc->seg_addr[i] = htole32(segs[i].ds_addr);
desc->seg_len[i] = htole32(segs[i].ds_len);
}
- bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
- BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE);
- DPRINTFN(5, ("sending data frame idx=%u len=%u nseg=%u\n", sc->txq.cur,
- desc->len, desc->nseg));
+ DPRINTFN(5, ("sending data frame txq=%u idx=%u len=%u nseg=%u\n",
+ ac, txq->cur, desc->len, desc->nseg));
- sc->txq.queued++;
- sc->txq.cur = (sc->txq.cur + 1) % IWI_TX_RING_COUNT;
- CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur);
+ txq->queued++;
+ txq->cur = (txq->cur + 1) % IWI_TX_RING_COUNT;
+ CSR_WRITE_4(sc, txq->csr_widx, txq->cur);
return 0;
}
@@ -1462,12 +1602,6 @@
if (m0 == NULL)
break;
- if (sc->txq.queued >= IWI_TX_RING_COUNT - 4) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m0);
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
-
if (m0->m_len < sizeof (struct ether_header) &&
(m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL)
continue;
@@ -1478,6 +1612,10 @@
m_freem(m0);
continue;
}
+ if (ieee80211_classify(ic, m0, ni) != 0) {
+ m_freem(m0);
+ continue;
+ }
BPF_MTAP(ifp, m0);
m0 = ieee80211_encap(ic, m0, ni);
@@ -1506,7 +1644,6 @@
iwi_watchdog(struct ifnet *ifp)
{
struct iwi_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = &sc->sc_ic;
IWI_LOCK(sc);
@@ -1524,8 +1661,6 @@
ifp->if_timer = 1;
}
- ieee80211_watchdog(ic);
-
IWI_UNLOCK(sc);
}
@@ -1542,10 +1677,10 @@
switch (cmd) {
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_flags & IFF_RUNNING))
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
iwi_init(sc);
} else {
- if (ifp->if_flags & IFF_RUNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
iwi_stop(sc);
}
break;
@@ -1574,8 +1709,9 @@
}
if (error == ENETRESET) {
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
- (IFF_UP | IFF_RUNNING))
+ if ((ifp->if_flags & IFF_UP) &&
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
+ (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
iwi_init(sc);
error = 0;
}
@@ -2102,6 +2238,7 @@
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_node *ni = ic->ic_bss;
+ struct ieee80211_wme_info wme;
struct iwi_configuration config;
struct iwi_associate assoc;
struct iwi_rateset rs;
@@ -2148,6 +2285,23 @@
if (error != 0)
return error;
+ if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) {
+ wme.wme_id = IEEE80211_ELEMID_VENDOR;
+ wme.wme_len = sizeof (struct ieee80211_wme_info) - 2;
+ wme.wme_oui[0] = 0x00;
+ wme.wme_oui[1] = 0x50;
+ wme.wme_oui[2] = 0xf2;
+ wme.wme_type = WME_OUI_TYPE;
+ wme.wme_subtype = WME_INFO_OUI_SUBTYPE;
+ wme.wme_version = WME_VERSION;
+ wme.wme_info = 0;
+
+ DPRINTF(("Setting WME IE (len=%u)\n", wme.wme_len));
+ error = iwi_cmd(sc, IWI_CMD_SET_WMEIE, &wme, sizeof wme, 1);
+ if (error != 0)
+ return error;
+ }
+
if (ic->ic_opt_ie != NULL) {
DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len));
error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie,
@@ -2168,8 +2322,10 @@
assoc.chan = ieee80211_chan2ieee(ic, ic->ic_bsschan);
if (ni->ni_authmode == IEEE80211_AUTH_SHARED)
assoc.auth = ic->ic_crypto.cs_def_txkey << 4 | IWI_AUTH_SHARED;
+ if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
+ assoc.policy |= htole16(IWI_POLICY_WME);
if (ic->ic_opt_ie != NULL)
- assoc.policy |= htole16(IWI_POLICY_OPTIE);
+ assoc.policy |= htole16(IWI_POLICY_WPA);
memcpy(assoc.tstamp, ni->ni_tstamp.data, 8);
if (ic->ic_opmode == IEEE80211_M_IBSS)
@@ -2240,21 +2396,21 @@
CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, sc->cmdq.count);
CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
- CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq.physaddr);
- CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq.count);
- CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur);
+ CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq[0].physaddr);
+ CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq[0].count);
+ CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq[0].cur);
- CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq.physaddr);
- CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq.count);
- CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq.cur);
+ CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq[1].physaddr);
+ CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq[1].count);
+ CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq[1].cur);
- CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq.physaddr);
- CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq.count);
- CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq.cur);
+ CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq[2].physaddr);
+ CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq[2].count);
+ CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq[2].cur);
- CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq.physaddr);
- CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq.count);
- CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq.cur);
+ CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq[3].physaddr);
+ CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq[3].count);
+ CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq[3].cur);
for (i = 0; i < sc->rxq.count; i++) {
data = &sc->rxq.data[i];
@@ -2275,13 +2431,14 @@
goto fail;
}
- if (ic->ic_opmode == IEEE80211_M_MONITOR)
+ if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+ if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+ } else
ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
- else
- ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
- ifp->if_flags &= ~IFF_OACTIVE;
- ifp->if_flags |= IFF_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
return;
@@ -2302,17 +2459,19 @@
/* reset rings */
iwi_reset_cmd_ring(sc, &sc->cmdq);
- iwi_reset_tx_ring(sc, &sc->txq);
+ iwi_reset_tx_ring(sc, &sc->txq[0]);
+ iwi_reset_tx_ring(sc, &sc->txq[1]);
+ iwi_reset_tx_ring(sc, &sc->txq[2]);
+ iwi_reset_tx_ring(sc, &sc->txq[3]);
iwi_reset_rx_ring(sc, &sc->rxq);
sc->sc_tx_timer = 0;
ifp->if_timer = 0;
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
}
-#ifdef IWI_DEBUG
static int
iwi_sysctl_stats(SYSCTL_HANDLER_ARGS)
{
@@ -2329,7 +2488,6 @@
return SYSCTL_OUT(req, buf, sizeof buf);
}
-#endif
static int
iwi_sysctl_radio(SYSCTL_HANDLER_ARGS)
==== //depot/projects/wifi/sys/dev/ral/if_ral.c#5 (text+ko) ====
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/ral/if_ral.c,v 1.10 2005/07/10 22:25:44 sam Exp $ */
+/* $FreeBSD: src/sys/dev/ral/if_ral.c,v 1.15 2005/08/21 14:16:19 damien Exp $ */
/*-
* Copyright (c) 2005
@@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.10 2005/07/10 22:25:44 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.15 2005/08/21 14:16:19 damien Exp $");
/*-
* Ralink Technology RT2500 chipset driver
@@ -91,7 +91,6 @@
static struct ieee80211_node *ral_node_alloc(
struct ieee80211_node_table *);
static int ral_media_change(struct ifnet *);
-static void ral_next_scan(void *);
static void ral_iter_func(void *, struct ieee80211_node *);
static void ral_update_rssadapt(void *);
static int ral_newstate(struct ieee80211com *,
@@ -105,7 +104,7 @@
static void ral_beacon_expire(struct ral_softc *);
static void ral_wakeup_expire(struct ral_softc *);
static void ral_intr(void *);
-static int ral_ack_rate(int);
+static int ral_ack_rate(struct ieee80211com *, int);
static uint16_t ral_txtime(int, int, uint32_t);
static uint8_t ral_plcp_signal(int);
static void ral_setup_tx_desc(struct ral_softc *,
@@ -350,7 +349,6 @@
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
- callout_init(&sc->scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
callout_init(&sc->rssadapt_ch, CALLOUT_MPSAFE);
/* retrieve RT2560 rev. no */
@@ -533,7 +531,6 @@
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = ic->ic_ifp;
- callout_stop(&sc->scan_ch);
callout_stop(&sc->rssadapt_ch);
bpfdetach(ifp);
@@ -921,27 +918,14 @@
if (error != ENETRESET)
return error;
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
+ if ((ifp->if_flags & IFF_UP) &&
+ (ifp->if_drv_flags & IFF_DRV_RUNNING))
ral_init(sc);
return 0;
}
/*
- * This function is called periodically (every 200ms) during scanning to
- * switch from one channel to another.
- */
-static void
-ral_next_scan(void *arg)
-{
- struct ral_softc *sc = arg;
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list