PERFORCE change 135686 for review
Andrew Thompson
thompsa at FreeBSD.org
Mon Feb 18 23:51:19 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=135686
Change 135686 by thompsa at thompsa_heff on 2008/02/18 23:50:54
MF //depot/user/benjsc/wpi/sys/dev/wpi/if_wpi.c at 131089
1. ic->ic_bsschan is the bss channel, not ni->ni_cha; it's well-defined in RUN
state so use it (other times it may be set to ANY)
2. remove watchdog_cnt since it does nothing bug duplicate sc_tx_timer
3. good drivers should never set channel state; remove code on SCAN_START
4. rewrite wpi_tx_start
5. calculate 802.11 header length correctly in wpi_tx_start
6. take ssid info from scan state, not ieee80211com; when a scan is
issued by a user application it may be differnt (if not now, then
in the future)
o Place some debug code in wpi_scan under debug
o Minor style changes (Note these don't include all the style changes provded by
sam - they'll be committed in a separate commit)
o Correct assoc state to fall through when not in RUN state
Applied from a slightly modified version originally submitted by
Submitted By: sam@ (With many thanks!)
Affected files ...
.. //depot/projects/wifi/sys/dev/wpi/if_wpi.c#9 edit
Differences ...
==== //depot/projects/wifi/sys/dev/wpi/if_wpi.c#9 (text+ko) ====
@@ -1339,8 +1339,8 @@
switch (nstate) {
case IEEE80211_S_SCAN:
- DPRINTF(("NEWSTATE:SCAN\n"));
- /* Scanning is handled in net80211 via the scan_start,
+ /*
+ * Scanning is handled in net80211 via the scan_start,
* scan_end, scan_curchan functions. Hence all we do when
* changing to the SCAN state is update the leds
*/
@@ -1352,11 +1352,10 @@
case IEEE80211_S_ASSOC:
DPRINTF(("NEWSTATE:ASSOC\n"));
if (ic->ic_state != IEEE80211_S_RUN)
- break;
+ break;
/* FALLTHROUGH */
case IEEE80211_S_AUTH:
- DPRINTF(("NEWSTATE:AUTH\n"));
sc->flags |= WPI_FLAG_AUTH;
sc->config.associd = 0;
sc->config.filter &= ~htole32(WPI_FILTER_BSS);
@@ -1365,7 +1364,6 @@
break;
case IEEE80211_S_RUN:
- DPRINTF(("NEWSTATE:RUN\n"));
if (ic->ic_opmode == IEEE80211_M_MONITOR) {
/* link LED blinks while monitoring */
wpi_set_led(sc, WPI_LED_LINK, 5, 5);
@@ -1409,7 +1407,7 @@
return error;
}
- if ((error = wpi_set_txpower(sc, ic->ic_bss->ni_chan, 1)) != 0) {
+ if ((error = wpi_set_txpower(sc, ic->ic_bsschan, 1)) != 0) {
device_printf(sc->sc_dev,
"could set txpower\n");
return error;
@@ -1428,9 +1426,6 @@
break;
case IEEE80211_S_INIT:
- DPRINTF(("NEWSTATE:INIT\n"));
- break;
-
default:
break;
}
@@ -1595,7 +1590,6 @@
struct wpi_rx_head *head;
struct wpi_rx_tail *tail;
struct wpi_rbuf *rbuf;
- struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m, *mnew;
WPI_LOCK_DECL;
@@ -1688,12 +1682,11 @@
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
}
- wh = mtod(m, struct ieee80211_frame *);
WPI_UNLOCK(sc);
/* XXX frame length > sizeof(struct ieee80211_frame_min)? */
/* grab a reference to the source node */
- ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
+ ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
/* send the frame to the 802.11 layer */
ieee80211_input(ic, m, ni, stat->rssi, 0, 0);
@@ -1746,7 +1739,6 @@
ring->queued--;
sc->sc_tx_timer = 0;
- sc->watchdog_cnt = 0;
callout_stop(&sc->watchdog_to);
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
wpi_start(ifp);
@@ -1855,9 +1847,6 @@
DPRINTFN(WPI_DEBUG_SCANNING,
("scanning channel %d status %x\n",
scan->chan, le32toh(scan->status)));
-
- /* fix current channel */
- ic->ic_bss->ni_chan = &ic->ic_channels[scan->chan];
break;
}
case WPI_STOP_SCAN:
@@ -1877,7 +1866,8 @@
struct wpi_missed_beacon *beacon =
(struct wpi_missed_beacon *)(desc + 1);
- if (le32toh(beacon->consecutive) >= ic->ic_bmissthreshold) {
+ if (le32toh(beacon->consecutive) >=
+ ic->ic_bmissthreshold) {
DPRINTF(("Beacon miss: %u >= %u\n",
le32toh(beacon->consecutive),
ic->ic_bmissthreshold));
@@ -1892,7 +1882,6 @@
/* tell the firmware what we have processed */
hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1;
WPI_WRITE(sc, WPI_RX_WIDX, hw & ~7);
-
}
static void
@@ -1977,6 +1966,7 @@
int ac)
{
struct ieee80211com *ic = &sc->sc_ic;
+ const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams;
struct wpi_tx_ring *ring = &sc->txq[ac];
struct wpi_tx_desc *desc;
struct wpi_tx_data *data;
@@ -1984,9 +1974,8 @@
struct wpi_cmd_data *tx;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
- const struct chanAccParams *cap;
struct mbuf *mnew;
- int i, error, nsegs, rate, hdrlen, noack = 0;
+ int i, error, nsegs, rate, hdrlen, ismcast;
bus_dma_segment_t segs[WPI_MAX_SCATTER];
desc = &ring->desc[ring->cur];
@@ -1994,60 +1983,19 @@
wh = mtod(m0, struct ieee80211_frame *);
- if (IEEE80211_QOS_HAS_SEQ(wh)) {
- hdrlen = sizeof (struct ieee80211_qosframe);
- cap = &ic->ic_wme.wme_chanParams;
- noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
- } else
- hdrlen = sizeof (struct ieee80211_frame);
+ hdrlen = ieee80211_hdrsize(wh);
+ ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- if ((k = ieee80211_crypto_encap(ic, ni, m0)) == NULL) {
+ 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 *);
}
- /* pickup a rate */
- if (IEEE80211_IS_MULTICAST(wh->i_addr1)||
- ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
- IEEE80211_FC0_TYPE_MGT)) {
- /*
- * mgmt/multicast frames are sent at the lowest available
- * bit-rate
- */
- rate = ni->ni_rates.rs_rates[0];
- } else {
- if (ic->ic_fixed_rate != -1) {
- rate = ic->ic_sup_rates[ic->ic_curmode].
- rs_rates[ic->ic_fixed_rate];
- } else
- rate = ni->ni_rates.rs_rates[ni->ni_txrate];
- }
- rate &= IEEE80211_RATE_VAL;
-
-#ifndef WPI_CURRENT
- if (sc->sc_drvbpf != NULL) {
-#else
- if (bpf_peers_present(sc->sc_drvbpf)) {
-#endif
-
- struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
- tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
- tap->wt_rate = rate;
- tap->wt_hwqueue = ac;
- if (wh->i_fc[1] & IEEE80211_FC1_WEP)
- tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
-
- bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
- }
-
cmd = &ring->cmd[ring->cur];
cmd->code = WPI_CMD_TX_DATA;
cmd->flags = 0;
@@ -2055,45 +2003,67 @@
cmd->idx = ring->cur;
tx = (struct wpi_cmd_data *)cmd->data;
- tx->flags = 0;
+ tx->flags = htole32(WPI_TX_AUTO_SEQ);
+ tx->timeout= htole16(0);
+ tx->ofdm_mask = 0xff;
+ tx->cck_mask = 0x0f;
+ tx->lifetime = htole32(WPI_LIFETIME_INFINITE);
+ tx->id = ismcast ? WPI_ID_BROADCAST : WPI_ID_BSS;
+ tx->len = htole16( m0->m_pkthdr.len);
- if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- tx->flags |= htole32(WPI_TX_NEED_ACK);
- } else if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
- tx->flags |= htole32(WPI_TX_NEED_RTS | WPI_TX_FULL_TXOP);
+ if (ismcast) {
+ if ((ni->ni_flags & IEEE80211_NODE_QOS) == 0 ||
+ !cap->cap_wmeParams[ac].wmep_noackPolicy)
+ tx->flags |= htole32(WPI_TX_NEED_ACK);
+ if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
+ tx->flags |= htole32(WPI_TX_NEED_RTS|WPI_TX_FULL_TXOP);
+ tx->rts_ntries = 7;
+ }
}
- tx->flags |= htole32(WPI_TX_AUTO_SEQ);
-
- tx->id = IEEE80211_IS_MULTICAST(wh->i_addr1) ? WPI_ID_BROADCAST :
- WPI_ID_BSS;
-
- if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
- IEEE80211_FC0_TYPE_MGT) {
+ /* pick a rate */
+ if((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MASK){
uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
/* tell h/w to set timestamp in probe responses */
if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
- tx->flags |= htole32(WPI_TX_INSERT_TSTAMP);
+ tx->flags |= htole32(WPI_TX_INSERT_TSTAMP);
if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
- subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
+ subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
tx->timeout = htole16(3);
else
tx->timeout = htole16(2);
- } else
- tx->timeout = htole16(0);
+ rate = ni->ni_rates.rs_rates[0] & IEEE80211_RATE_VAL;
+ } else if (ismcast ){
+ rate = ic->ic_mcast_rate;
+ } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE){
+ rate = ic->ic_fixed_rate;
+ } else {
+ rate = ni->ni_rates.rs_rates[ni->ni_txrate];
+ rate &= IEEE80211_RATE_VAL;
+ }
tx->rate = wpi_plcp_signal(rate);
/* be very persistant at sending frames out */
- tx->rts_ntries = 7;
- tx->data_ntries = 15;
+ tx->data_ntries = 15; /* XXX Way too high */
- tx->ofdm_mask = 0xff;
- tx->cck_mask = 0x0f;
- tx->lifetime = htole32(WPI_LIFETIME_INFINITE);
+#ifndef WPI_CURRENT
+ if (sc->sc_drvbpf != NULL ){
+#else
+ if (bpf_peers_present(sc->sc_drvbpf)){
+#endif
+ struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
+ tap->wt_flags = 0;
+ tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
+ tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
+ tap->wt_rate = rate;
+ tap->wt_hwqueue = ac;
+ if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+ tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
- tx->len = htole16(m0->m_pkthdr.len);
+ bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+ }
/* save and trim IEEE802.11 header */
m_copydata(m0, 0, hdrlen, (caddr_t)&tx->wh);
@@ -2227,10 +2197,7 @@
continue;
}
- /* no QoS encapsulation for EAPOL frames */
- ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
- M_WME_GETAC(m0) : WME_AC_BE;
-
+ ac = M_WME_GETAC(m0);
if (sc->txq[ac].queued > sc->txq[ac].count - 8) {
/* there is no place left in this ring */
IFQ_DRV_PREPEND(&ifp->if_snd, m0);
@@ -2262,7 +2229,6 @@
}
sc->sc_tx_timer = 5;
- sc->watchdog_cnt = 5;
ic->ic_lastdata = ticks;
}
@@ -2277,17 +2243,12 @@
WPI_LOCK(sc);
- DPRINTFN(WPI_DEBUG_WATCHDOG, ("watchdog_cnt: %d\n", sc->watchdog_cnt));
-
- if (sc->watchdog_cnt == 0 || --sc->watchdog_cnt)
- goto done;
-
- if (--sc->sc_tx_timer != 0) {
+ DPRINTFN(WPI_DEBUG_WATCHDOG, ("tx_timer: %d\n", sc->sc_tx_timer));
+ if (sc->sc_tx_timer && --sc->sc_tx_timer != 0) {
device_printf(sc->sc_dev,"device timeout\n");
ifp->if_oerrors++;
taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask);
}
-done:
WPI_UNLOCK(sc);
}
@@ -2685,6 +2646,7 @@
wpi_scan(struct wpi_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_scan_state *ss = ic->ic_scan;
struct wpi_tx_ring *ring = &sc->cmdq;
struct wpi_tx_desc *desc;
struct wpi_tx_data *data;
@@ -2696,7 +2658,7 @@
struct ieee80211_channel *c;
enum ieee80211_phymode mode;
uint8_t *frm;
- int nrates, pktlen, error;
+ int nrates, pktlen, error, i, nssid;
bus_addr_t physaddr;
struct ifnet *ifp = ic->ic_ifp;
@@ -2743,17 +2705,21 @@
hdr->tx.flags = htole32(WPI_TX_AUTO_SEQ);
/*XXX Need to cater for multiple essids */
- memset(&hdr->scan_essids[0], 0, 4 * sizeof(hdr->scan_essids[0]));
- hdr->scan_essids[0].id = IEEE80211_ELEMID_SSID;
- hdr->scan_essids[0].esslen = ic->ic_des_ssid[0].len;
- memcpy(hdr->scan_essids[0].essid, ic->ic_des_ssid[0].ssid,
- ic->ic_des_ssid[0].len);
-
- if (wpi_debug & WPI_DEBUG_SCANNING) {
+ memset(&hdr->scan_essids, 0, sizeof(hdr->scan_essids));
+ nssid = MIN(ss->ss_nssid, WPI_SCAN_MAX_ESSIDS);
+ for(i = 0; i < nssid; i++ ){
+ hdr->scan_essids[i].id = IEEE80211_ELEMID_SSID;
+ hdr->scan_essids[i].esslen = MIN(ss->ss_ssid[i].len, 32);
+ memcpy(hdr->scan_essids[i].essid, ss->ss_ssid[i].ssid,
+ hdr->scan_essids[i].esslen);
+#ifdef WPI_DEBUG
+ if (wpi_debug & WPI_DEBUG_SCANNING) {
printf("Scanning Essid: ");
- ieee80211_print_essid(ic->ic_des_ssid[0].ssid,
- ic->ic_des_ssid[0].len);
+ ieee80211_print_essid(ic->ic_des_ssid[i].ssid,
+ ic->ic_des_ssid[i].len);
printf("\n");
+ }
+#endif
}
/*
@@ -3259,7 +3225,7 @@
uint32_t tmp;
int ac;
- sc->watchdog_cnt = sc->sc_tx_timer = 0;
+ sc->sc_tx_timer = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
/* disable interrupts */
@@ -3905,7 +3871,7 @@
default:
KASSERT(1, ("Unknown Command: %d\n", cmd));
- return "UNKNOWN CMD"; // Make the compiler happy
+ return "UNKNOWN CMD"; /* Make the compiler happy */
}
}
#endif
More information about the p4-projects
mailing list