Current-Users archive

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

Re: iwn0 driver: status



On Sat, Jul 19, 2008 at 10:05:47PM +0200, Marcin M. Jessa wrote:
> 
> The iwn wlan nic still cannot connect to my AP but it stopped spiting out 
> those hideous messages.

Try the attached patch applied to src/sys/dev/pci/if_iwn.c.  I have
had reports that with the patch people are able to connect to their AP
if they are using a static WEP key.

My set up at home uses WPA and I have more erratic results with
connections to my AP using WPA.  Sometimes I will get the WPA session
negotiated fine first time without doing anything, other times the
negotiation continually times out - the wireless NIC finds the AP but
they never seem to get things right.  I have found if the negotiation
times out that if I boot to Windows on the laptop first and then
reboot to NetBSD the negotiation works and will continue to work over
multiple reboots of NetBSD - it seems that Windows does "something" to
the AP that makes the negotiation work for as long as my wireless
router stays up.  This issue is what has stopped me committing what I
have done - I have been poring over the Linux driver to see if there
are bits we are missing from the authentication negotiation which has
been a bit slow going since the linux wireless code is organised (?)
very differently.

The good thing about the driver is once the WPA is negotiated the
connection seems very stable

Anyway, try the patch and let us know how you go.

-- 
Brett Lymn
"Warning:
The information contained in this email and any attached files is
confidential to BAE Systems Australia. If you are not the intended
recipient, any use, disclosure or copying of this email or any
attachments is expressly prohibited.  If you have received this email
in error, please notify us immediately. VIRUS: Every care has been
taken to ensure this email and its attachments are virus free,
however, any loss or damage incurred in using this email is not the
sender's responsibility.  It is your responsibility to ensure virus
checks are completed before installing any data sent in this email to
your computer."

Index: if_iwn.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.10
diff -u -r1.10 if_iwn.c
--- if_iwn.c    10 May 2008 12:56:28 -0000      1.10
+++ if_iwn.c    20 Jul 2008 08:57:01 -0000
@@ -144,7 +144,6 @@
 static int             iwn_intr(void *);
 static void            iwn_read_eeprom(struct iwn_softc *);
 static void            iwn_read_eeprom_channels(struct iwn_softc *, int);
-static void            iwn_print_power_group(struct iwn_softc *, int);
 static uint8_t         iwn_plcp_signal(int);
 static int             iwn_tx_data(struct iwn_softc *, struct mbuf *,
     struct ieee80211_node *, int);
@@ -182,6 +181,8 @@
 static void            iwn_stop(struct ifnet *, int);
 static void            iwn_fix_channel(struct ieee80211com *, struct mbuf *);
 static bool            iwn_resume(device_t PMF_FN_PROTO);
+static int             iwn_add_node(struct iwn_softc *sc,
+       struct ieee80211_node *ni, bool broadcast);
 
 
 
@@ -190,12 +191,16 @@
 #ifdef IWN_DEBUG
 #define DPRINTF(x)     do { if (iwn_debug > 0) printf x; } while (0)
 #define DPRINTFN(n, x) do { if (iwn_debug >= (n)) printf x; } while (0)
-int iwn_debug = 2;
+int iwn_debug = 0;
 #else
 #define DPRINTF(x)
 #define DPRINTFN(n, x)
 #endif
 
+#ifdef IWN_DEBUG
+static void            iwn_print_power_group(struct iwn_softc *, int);
+#endif
+
 CFATTACH_DECL_NEW(iwn, sizeof(struct iwn_softc), iwn_match, iwn_attach,
     iwn_detach, NULL);
 
@@ -467,7 +472,6 @@
  * Build a beacon frame that the firmware will broadcast periodically in
  * IBSS or HostAP modes.
  */
-#if 0
 static int
 iwn_setup_beacon(struct iwn_softc *sc, struct ieee80211_node *ni)
 {
@@ -538,7 +542,6 @@
 
        return 0;
 }
-#endif
 
 static int
 iwn_dma_contig_alloc(bus_dma_tag_t tag, struct iwn_dma_info *dma, void **kvap,
@@ -976,6 +979,9 @@
 
        callout_stop(&sc->calib_to);
 
+       DPRINTF(("iwn_newstate: nstate = %d, ic->ic_state = %d\n", nstate,
+               ic->ic_state));
+
        switch (nstate) {
 
        case IEEE80211_S_SCAN:
@@ -1414,6 +1420,7 @@
                len = le16toh(stat->len);
        }
 
+       DPRINTF(("rx packet len %d\n", len));
        /* discard Rx frames with bad CRC early */
        tail = (uint32_t *)(head + len);
        if ((le32toh(*tail) & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
@@ -1903,6 +1910,8 @@
        uint8_t type;
        int i, error, pad, rate, hdrlen, noack = 0;
 
+       DPRINTFN(5, ("iwn_tx_data entry\n"));
+
        desc = &ring->desc[ring->cur];
        data = &ring->data[ring->cur];
 
@@ -1927,8 +1936,7 @@
        }
 
        /* pickup a rate */
-       if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
-           IEEE80211_FC0_TYPE_MGT) {
+       if (type == IEEE80211_FC0_TYPE_MGT) {
                /* mgmt frames are sent at the lowest available bit-rate */
                rate = ni->ni_rates.rs_rates[0];
        } else {
@@ -1972,17 +1980,24 @@
 
        tx->id = IEEE80211_IS_MULTICAST(wh->i_addr1) ? IWN_ID_BROADCAST : 
IWN_ID_BSS;
 
+       DPRINTFN(5, ("addr1: %x:%x:%x:%x:%x:%x, id = 0x%x\n",
+                    wh->i_addr1[0], wh->i_addr1[1], wh->i_addr1[2],
+                    wh->i_addr1[3], wh->i_addr1[4], wh->i_addr1[5], tx->id));
+
        if (type == IEEE80211_FC0_TYPE_MGT) {
                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)
+               if ((subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) ||
+                   (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ))
                        flags |= IWN_TX_INSERT_TSTAMP;
 
                if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
-                   subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
+                   subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
+                       flags &= ~IWN_TX_NEED_RTS;
+                       flags |= IWN_TX_NEED_CTS;
                        tx->timeout = htole16(3);
-               else
+               } else
                        tx->timeout = htole16(2);
        } else
                tx->timeout = htole16(0);
@@ -1994,6 +2009,16 @@
        } else
                pad = 0;
 
+       if (type == IEEE80211_FC0_TYPE_CTL) {
+               uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+               /* tell h/w to set timestamp in probe responses */
+               if (subtype == 0x0080) /* linux says this is "back request" */
+                       /* linux says (1 << 6) is IMM_BA_RSP_MASK */
+                       flags |= (IWN_TX_NEED_ACK | (1 << 6));
+       }
+
+
        tx->flags = htole32(flags);
        tx->len = htole16(m0->m_pkthdr.len);
        tx->rate = iwn_plcp_signal(rate);
@@ -2100,6 +2125,8 @@
        struct mbuf *m0;
        int ac;
 
+       DPRINTFN(5, ("iwn_start enter\n"));
+
        /*
         * net80211 may still try to send management frames even if the
         * IFF_RUNNING flag is not set...
@@ -3074,11 +3101,48 @@
 }
 
 static int
+iwn_add_node(struct iwn_softc *sc, struct ieee80211_node *ni, bool broadcast)
+{
+       struct iwn_node_info node;
+       int error;
+
+       error = 0;
+
+       memset(&node, 0, sizeof node);
+       if (broadcast == true) {
+               IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
+               node.id = IWN_ID_BROADCAST;
+               DPRINTF(("adding broadcast node\n"));
+       } else {
+               IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
+               node.id = IWN_ID_BSS;
+               node.htflags = htole32(3 << IWN_AMDPU_SIZE_FACTOR_SHIFT |
+                                      5 << IWN_AMDPU_DENSITY_SHIFT);
+               DPRINTF(("adding BSS node\n"));
+       }
+
+       error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 0);
+       if (error != 0) {
+               aprint_error_dev(sc->sc_dev, "could not add %s node\n",
+                                (broadcast == 1)? "broadcast" : "BSS");
+               return error;
+       }
+       DPRINTF(("setting MRR for node %d\n", node.id));
+       if ((error = iwn_setup_node_mrr(sc, node.id, 1)) != 0) {
+               aprint_error_dev(sc->sc_dev,
+                                "could not setup MRR for %s node\n",
+                                (broadcast == 1)? "broadcast" : "BSS");
+               return error;
+       }
+
+       return error;
+}
+
+static int
 iwn_auth(struct iwn_softc *sc)
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211_node *ni = ic->ic_bss;
-       struct iwn_node_info node;
        int error;
 
        /* update adapter's configuration */
@@ -3121,21 +3185,24 @@
         * Reconfiguring clears the adapter's nodes table so we must
         * add the broadcast node again.
         */
-       memset(&node, 0, sizeof node);
-       IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
-       node.id = IWN_ID_BROADCAST;
-       DPRINTF(("adding broadcast node\n"));
-       error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
-       if (error != 0) {
-               aprint_error_dev(sc->sc_dev, "could not add broadcast node\n");
+       if ((error = iwn_add_node(sc, ni, true)) != 0)
                return error;
+
+       /* add BSS node */
+       if ((error = iwn_add_node(sc, ni, false)) != 0)
+               return error;
+
+       if (ic->ic_opmode == IEEE80211_M_STA) {
+               /* fake a join to init the tx rate */
+               iwn_newassoc(ni, 1);
        }
-       DPRINTF(("setting MRR for node %d\n", node.id));
-       if ((error = iwn_setup_node_mrr(sc, node.id, 1)) != 0) {
-               aprint_error_dev(sc->sc_dev, "could not setup MRR for broadcast 
node\n");
+
+       if ((error = iwn_init_sensitivity(sc)) != 0) {
+               aprint_error_dev(sc->sc_dev, "could not set sensitivity\n");
                return error;
        }
 
+
        return 0;
 }
 
@@ -3147,7 +3214,6 @@
 {
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211_node *ni = ic->ic_bss;
-       struct iwn_node_info node;
        int error;
 
        if (ic->ic_opmode == IEEE80211_M_MONITOR) {
@@ -3174,7 +3240,8 @@
        error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
            sizeof (struct iwn_config), 1);
        if (error != 0) {
-               aprint_error_dev(sc->sc_dev, "could not update 
configuration\n");
+               aprint_error_dev(sc->sc_dev,
+                       "could not update configuration\n");
                return error;
        }
 
@@ -3185,22 +3252,7 @@
        }
 
        /* add BSS node */
-       memset(&node, 0, sizeof node);
-       IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
-       node.id = IWN_ID_BSS;
-       node.htflags = htole32(3 << IWN_AMDPU_SIZE_FACTOR_SHIFT |
-           5 << IWN_AMDPU_DENSITY_SHIFT);
-       DPRINTF(("adding BSS node\n"));
-       error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
-       if (error != 0) {
-               aprint_error_dev(sc->sc_dev, "could not add BSS node\n");
-               return error;
-       }
-       DPRINTF(("setting MRR for node %d\n", node.id));
-       if ((error = iwn_setup_node_mrr(sc, node.id, 1)) != 0) {
-               aprint_error_dev(sc->sc_dev, "could not setup MRR for node 
%d\n", node.id);
-               return error;
-       }
+       iwn_add_node(sc, ni, false);
 
        if (ic->ic_opmode == IEEE80211_M_STA) {
                /* fake a join to init the tx rate */
@@ -3217,6 +3269,16 @@
        sc->calib_cnt = 0;
        callout_schedule(&sc->calib_to, hz / 2);
 
+       /* now we are associated set up the beacon frame */
+       if (0 == 1) {
+
+       if ((error = iwn_setup_beacon(sc, ni))) {
+               aprint_error_dev(sc->sc_dev, "could not setup beacon frame\n");
+               return error;
+       }
+       }
+
+
        /* link LED always on while associated */
        iwn_set_led(sc, IWN_LED_LINK, 0, 1);
 
@@ -3415,7 +3477,6 @@
        struct ifnet *ifp = ic->ic_ifp;
        struct iwn_power power;
        struct iwn_bluetooth bluetooth;
-       struct iwn_node_info node;
        int error;
 
        /* set power mode */
@@ -3492,20 +3553,8 @@
        }
 
        /* add broadcast node */
-       memset(&node, 0, sizeof node);
-       IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
-       node.id = IWN_ID_BROADCAST;
-       DPRINTF(("adding broadcast node\n"));
-       error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 0);
-       if (error != 0) {
-               aprint_error_dev(sc->sc_dev, "could not add broadcast node\n");
+       if ((error = iwn_add_node(sc, NULL, true)) != 0)
                return error;
-       }
-       DPRINTF(("setting MRR for node %d\n", node.id));
-       if ((error = iwn_setup_node_mrr(sc, node.id, 0)) != 0) {
-               aprint_error_dev(sc->sc_dev, "could not setup MRR for node 
%d\n", node.id);
-               return error;
-       }
 
        if ((error = iwn_set_critical_temp(sc)) != 0) {
                aprint_error_dev(sc->sc_dev, "could not set critical 
temperature\n");


Home | Main Index | Thread Index | Old Index