Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Replace iwn_tx from rev. 1.39 with a port of the...



details:   https://anonhg.NetBSD.org/src/rev/c884a6d60f08
branches:  trunk
changeset: 754495:c884a6d60f08
user:      christos <christos%NetBSD.org@localhost>
date:      Sun May 02 02:06:15 2010 +0000

description:
Replace iwn_tx from rev. 1.39 with a port of the current OpenBSD version.
Remove superfluous call to bpf_detach.
Add comments regarding porting issues and add a couple of cosmetic changes
that reduce the diffs to the OpenBSD version. From Sverre Froyen

diffstat:

 sys/dev/pci/if_iwn.c |  460 ++++++++------------------------------------------
 1 files changed, 80 insertions(+), 380 deletions(-)

diffs (truncated from 659 to 300 lines):

diff -r 4d4a3c6bc740 -r c884a6d60f08 sys/dev/pci/if_iwn.c
--- a/sys/dev/pci/if_iwn.c      Sat May 01 23:54:35 2010 +0000
+++ b/sys/dev/pci/if_iwn.c      Sun May 02 02:06:15 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_iwn.c,v 1.43 2010/04/28 15:56:24 christos Exp $     */
+/*     $NetBSD: if_iwn.c,v 1.44 2010/05/02 02:06:15 christos Exp $     */
 /*     $OpenBSD: if_iwn.c,v 1.88 2010/04/10 08:37:36 damien Exp $      */
 
 /*-
@@ -22,7 +22,7 @@
  * adapters.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.43 2010/04/28 15:56:24 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.44 2010/05/02 02:06:15 christos Exp $");
 
 #define IWN_USE_RBUF   /* Use local storage for RX */
 #undef IWN_HWCRYPTO    /* XXX does not even compile yet */
@@ -638,13 +638,17 @@
 #endif
        iwn_radiotap_attach(sc);
 
-       /* timeout_set replaced by callout_init and callout_setfunc, above. */
+       /*
+        * XXX for NetBSD, OpenBSD timeout_set replaced by
+        * callout_init and callout_setfunc, above.
+       */
 
        if (pmf_device_register(self, NULL, iwn_resume))
                pmf_class_network_register(self, ifp);
        else
                aprint_error_dev(self, "couldn't establish power handler\n");
 
+       /* XXX NetBSD add call to ieee80211_announce for dmesg. */
        ieee80211_announce(ic);
 
        return;
@@ -844,10 +848,6 @@
        sysmon_envsys_destroy(sc->sc_sme);
 #endif
 
-       /* XXX verify that this is needed */
-       if (ifp != NULL)
-               bpf_detach(ifp);
-
        ieee80211_ifdetach(&sc->sc_ic);
        if_detach(ifp);
 
@@ -1153,6 +1153,7 @@
        if (error != 0)
                goto fail;
 
+       /* XXX Presumably needed because of missing BUS_DMA_ZERO, above. */
        memset(dma->vaddr, 0, size);
        bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
 
@@ -1651,6 +1652,7 @@
        DPRINTF(("calib version=%u pa type=%u voltage=%u\n",
            hdr.version, hdr.pa_type, le16toh(hdr.volt)));
        sc->calib_ver = hdr.version;
+
        if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
                /* Compute temperature offset. */
                iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
@@ -1830,12 +1832,14 @@
 
        switch (nstate) {
        case IEEE80211_S_SCAN:
+               /* XXX Do not abort a running scan. */
                if (sc->sc_flags & IWN_FLAG_SCANNING) {
                        aprint_error_dev(sc->sc_dev,
                            "scan request while scanning ignored\n");
                        break;
                }
 
+               /* XXX Not sure if call and flags are needed. */
                ieee80211_node_table_reset(&ic->ic_scan);
                ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
                sc->sc_flags |= IWN_FLAG_SCANNING;
@@ -1954,9 +1958,6 @@
        struct ieee80211com *ic = &sc->sc_ic;
        struct ifnet *ifp = ic->ic_ifp;
        struct iwn_rx_ring *ring = &sc->rxq;
-#if 0
-       struct iwn_rbuf *rbuf;
-#endif
        struct ieee80211_frame *wh;
        struct ieee80211_node *ni;
        struct mbuf *m, *m1;
@@ -2059,8 +2060,12 @@
        wh = mtod(m, struct ieee80211_frame *);
        ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
 
+       /* XXX OpenBSD adds decryption here (see also comments in iwn_tx). */
+       /* NetBSD does decryption in ieee80211_input. */
+
        rssi = hal->get_rssi(stat);
 
+       /* XXX Added for NetBSD: scans never stop without it */
        if (ic->ic_state == IEEE80211_S_SCAN)
                iwn_fix_channel(ic, m);
 
@@ -2616,7 +2621,7 @@
                tmp = le32toh(tmp);
                if (tmp == 0xffffffff)  /* Shouldn't happen. */
                        tmp = 0;
-               else if (tmp & 0xc0000) /* Workaround a HW bug. */
+               else if (tmp & 0xc0000) /* Workaround a HW bug. */
                        tmp |= 0x8000;
                r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
                r2 = 0; /* Unused. */
@@ -2754,8 +2759,6 @@
 }
 #endif
 
-#if 0
-/* XXX figure out why this (new OpenBSD) version does not work (on NetBSD! */
 static int
 iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
 {
@@ -2782,10 +2785,10 @@
        int hdrlen2;
 
        wh = mtod(m, struct ieee80211_frame *);
-       hdrlen2 = ieee80211_hdrsize(wh);
+       hdrlen = ieee80211_anyhdrsize(wh);
        type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 
-       hdrlen = (IEEE80211_QOS_HAS_SEQ(wh)) ?
+       hdrlen2 = (IEEE80211_QOS_HAS_SEQ(wh)) ?
            sizeof (struct ieee80211_qosframe) :
            sizeof (struct ieee80211_frame);
 
@@ -2793,19 +2796,14 @@
            aprint_error_dev(sc->sc_dev, "hdrlen error (%d != %d)\n",
                hdrlen, hdrlen2);
 
+       /* XXX OpenBSD sets a different tid when using QOS */
        tid = 0;
-
-       /* Encrypt the frame if need be. */
-       /* XXX Should this be after bpf_mtap2 call, below (see OpenBSD code)? */
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-               k = ieee80211_crypto_encap(ic, ni, m);
-               if (k == NULL) {
-                       m_freem(m);
-                       return ENOBUFS;
-               }
-               /* Packet header may have moved, reset our local pointer. */
-               wh = mtod(m, struct ieee80211_frame *);
-       }
+       if (IEEE80211_QOS_HAS_SEQ(wh)) {
+               cap = &ic->ic_wme.wme_chanParams;
+               noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
+       }
+       else
+               noack = 0;
 
        ring = &sc->txq[ac];
        desc = &ring->desc[ring->cur];
@@ -2822,6 +2820,24 @@
                ridx = wn->ridx[ni->ni_txrate];
        rinfo = &iwn_rates[ridx];
 
+       /* Encrypt the frame if need be. */
+       /*
+        * XXX For now, NetBSD swaps the encryption and bpf sections
+        * in order to match old code and other drivers. Tests with
+        * tcpdump indicates that the order is irrelevant, however,
+        * as bpf produces unencrypted data for both ordering choices.
+        */
+       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               k = ieee80211_crypto_encap(ic, ni, m);
+               if (k == NULL) {
+                       m_freem(m);
+                       return ENOBUFS;
+               }
+               /* Packet header may have moved, reset our local pointer. */
+               wh = mtod(m, struct ieee80211_frame *);
+       }
+       totlen = m->m_pkthdr.len;
+
        if (sc->sc_drvbpf != NULL) {
                struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
 
@@ -2836,8 +2852,6 @@
                bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
        }
 
-       totlen = m->m_pkthdr.len;
-
        /* Prepare TX firmware command. */
        cmd = &ring->cmd[ring->cur];
        cmd->code = IWN_CMD_TX_DATA;
@@ -2849,19 +2863,21 @@
        /* NB: No need to clear tx, all fields are reinitialized here. */
        tx->scratch = 0;        /* clear "scratch" area */
 
-       if (IEEE80211_QOS_HAS_SEQ(wh)) {
-               cap = &ic->ic_wme.wme_chanParams;
-               noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
-       }
-       else
-               noack = 0;
-
        flags = 0;
-       if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-               /* Unicast frame with an ACK expected. */
+       if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+               /* Unicast frame, check if an ACK is expected. */
+               if (!noack)
                        flags |= IWN_TX_NEED_ACK;
        }
 
+#ifdef notyet
+       /* XXX NetBSD does not define IEEE80211_FC0_SUBTYPE_BAR */
+       if ((wh->i_fc[0] &
+           (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
+           (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR))
+               flags |= IWN_TX_IMM_BA;         /* Cannot happen yet. */
+#endif          
+
        if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
                flags |= IWN_TX_MORE_FRAG;      /* Cannot happen yet. */
 
@@ -2898,9 +2914,13 @@
 
 #ifndef IEEE80211_STA_ONLY
                /* Tell HW to set timestamp in probe responses. */
+               /* XXX NetBSD rev 1.11 added probe requests here but */
+               /* probe requests do not take timestamps (from Bergamini). */
                if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
                        flags |= IWN_TX_INSERT_TSTAMP;
 #endif
+               /* XXX NetBSD rev 1.11 and 1.20 added AUTH/DAUTH and RTS/CTS */
+               /* changes here. These are not needed (from Bergamini). */
                if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
                    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
                        tx->timeout = htole16(3);
@@ -2910,7 +2930,7 @@
                tx->timeout = htole16(0);
 
        if (hdrlen & 3) {
-               /* First segment length must be a multiple of 4. */
+               /* First segment's length must be a multiple of 4. */
                flags |= IWN_TX_NEED_PADDING;
                pad = 4 - (hdrlen & 3);
        } else
@@ -2938,8 +2958,12 @@
        tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
 
        /* Copy 802.11 header in TX command. */
-       memcpy((uint8_t *)(tx + 1), wh, hdrlen);
-
+       /* XXX NetBSD changed this in rev 1.20 */
+       memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
+
+       /* Trim 802.11 header. */
+       m_adj(m, hdrlen);
+       tx->security = 0;
        tx->flags = htole32(flags);
 
        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
@@ -2965,7 +2989,7 @@
                                return ENOBUFS;
                        }
                }
-               m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, char *));
+               m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, void *));
                m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
                m_freem(m);
                m = m1;
@@ -3025,341 +3049,6 @@
 
        return 0;
 }
-#else
-/* This version is from the old NetBSD driver port */
-static int
-iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
-{
-       const struct iwn_hal *hal = sc->sc_hal;
-       struct ieee80211com *ic = &sc->sc_ic;
-       struct iwn_node *wn = (void *)ni;
-       struct iwn_tx_ring *ring;
-       struct iwn_tx_desc *desc;
-       struct iwn_tx_data *data;
-       struct iwn_tx_cmd *cmd;
-       struct iwn_cmd_data *tx;
-       const struct iwn_rate *rinfo;
-       struct ieee80211_frame *wh;
-       struct ieee80211_key *k = NULL;
-       const struct chanAccParams *cap;
-       struct mbuf *m1;
-       uint32_t flags;
-       u_int hdrlen;
-       bus_dma_segment_t *seg;
-       uint8_t ridx, txant, type;
-       int i, totlen, error, pad, noack;
-



Home | Main Index | Thread Index | Old Index