[802.11] Debug and output cleanup, minor association improvements
[people/oremanj/gpxe.git] / src / net / net80211.c
index 315ed0d..5ae0e2b 100644 (file)
@@ -440,36 +440,38 @@ static int net80211_ll_pull ( struct net_device *netdev __unused,
        /* Bunch of sanity checks */
        if ( iob_len ( iobuf ) < IEEE80211_TYP_FRAME_HEADER_LEN +
             IEEE80211_LLC_HEADER_LEN ) {
-               DBG ( "802.11 packet too short (%zd bytes)\n",
-                     iob_len ( iobuf ) );
+               DBGC ( netdev->priv, "802.11 %p packet too short (%zd bytes)\n",
+                      netdev->priv, iob_len ( iobuf ) );
                return -EINVAL_PKT_TOO_SHORT;
        }
 
        if ( ( hdr->fc & IEEE80211_FC_VERSION ) != IEEE80211_THIS_VERSION ) {
-               DBG ( "802.11 packet invalid version %04x\n",
-                     hdr->fc & IEEE80211_FC_VERSION );
+               DBGC ( netdev->priv, "802.11 %p packet invalid version %04x\n",
+                      netdev->priv, hdr->fc & IEEE80211_FC_VERSION );
                return -EINVAL_PKT_VERSION;
        }
 
        if ( ( hdr->fc & IEEE80211_FC_TYPE ) != IEEE80211_TYPE_DATA ||
             ( hdr->fc & IEEE80211_FC_SUBTYPE ) != IEEE80211_STYPE_DATA ) {
-               DBG ( "802.11 packet not data/data (fc=%04x)\n", hdr->fc );
+               DBGC ( netdev->priv, "802.11 %p packet not data/data (fc=%04x)\n",
+                      netdev->priv, hdr->fc );
                return -EINVAL_PKT_NOT_DATA;
        }
 
        if ( ( hdr->fc & ( IEEE80211_FC_TODS | IEEE80211_FC_FROMDS ) ) !=
             IEEE80211_FC_FROMDS ) {
-               DBG ( "802.11 packet not from DS (fc=%04x)\n", hdr->fc );
+               DBGC ( netdev->priv, "802.11 %p packet not from DS (fc=%04x)\n",
+                      netdev->priv, hdr->fc );
                return -EINVAL_PKT_NOT_FROMDS;
        }
 
        if ( lhdr->dsap != IEEE80211_LLC_DSAP || lhdr->ssap != IEEE80211_LLC_SSAP ||
             lhdr->ctrl != IEEE80211_LLC_CTRL || lhdr->oui[0] || lhdr->oui[1] ||
             lhdr->oui[2] ) {
-               DBG ( "802.11 LLC header is not plain EtherType encapsulator: "
-                     "%02x->%02x [%02x] %02x:%02x:%02x %04x\n",
-                     lhdr->dsap, lhdr->ssap, lhdr->ctrl, lhdr->oui[0],
-                     lhdr->oui[1], lhdr->oui[2], lhdr->ethertype );
+               DBGC ( netdev->priv, "802.11 %p LLC header is not plain EtherType "
+                      "encapsulator: %02x->%02x [%02x] %02x:%02x:%02x %04x\n",
+                      netdev->priv, lhdr->dsap, lhdr->ssap, lhdr->ctrl,
+                      lhdr->oui[0], lhdr->oui[1], lhdr->oui[2], lhdr->ethertype );
                return -EINVAL_PKT_LLC_HEADER;
        }
 
@@ -823,12 +825,13 @@ static int net80211_process_capab ( struct net80211_device *dev,
 
        if ( ( capab & ( IEEE80211_CAPAB_MANAGED | IEEE80211_CAPAB_ADHOC ) ) !=
             IEEE80211_CAPAB_MANAGED ) {
-               DBG ( "802.11 cannot handle IBSS network\n" );
+               DBGC ( dev, "802.11 %p cannot handle IBSS network\n", dev );
                return -ENOSYS;
        }
 
        if ( capab & IEEE80211_CAPAB_SPECTRUM_MGMT ) {
-               DBG ( "802.11 cannot handle spectrum managed network\n" );
+               DBGC ( dev, "802.11 %p cannot handle spectrum managed "
+                      "network\n", dev );
                return -ENOSYS;
        }
 
@@ -908,12 +911,13 @@ static int net80211_process_ie ( struct net80211_device *dev,
                case IEEE80211_IE_COUNTRY:
                        dev->nr_channels = 0;
 
-                       DBG ( "802.11 setting country regulations for %c%c\n",
-                             ie->country.name[0], ie->country.name[1] );
+                       DBGC ( dev, "802.11 %p setting country regulations "
+                              "for %c%c\n", dev, ie->country.name[0],
+                              ie->country.name[1] );
                        for ( i = 0; i < ( ie->len - 3 ) / 3; i++ ) {
                                if ( ie->country.triplet[i].ext.reg_ext_id > 200 ) {
-                                       DBG ( "802.11 don't know how to parse "
-                                             "regulatory extension information\n" );
+                                       DBGC ( dev, "802.11 %p ignoring regulatory "
+                                              "extension information\n", dev );
                                } else {
                                        net80211_add_channels ( dev,
                                          ie->country.triplet[i].band.first_channel,
@@ -1045,7 +1049,7 @@ net80211_marshal_request_info ( struct net80211_device *dev,
 }
 
 /** Seconds to always take when probing, to gather better signal strengths */
-#define NET80211_PROBE_GATHER    4
+#define NET80211_PROBE_GATHER    2
 
 /** Seconds to allow a probe to take, if no usable AP has yet been found */
 #define NET80211_PROBE_TIMEOUT   6
@@ -1139,8 +1143,9 @@ struct net80211_wlan * net80211_probe ( struct net80211_device *dev,
                                                        net80211_ll_broadcast,
                                                        iob_disown ( piob ) );
                                if ( rc ) {
-                                       DBG ( "802.11 send probe failed: %s\n",
-                                             strerror ( rc ) );
+                                       DBGC ( dev, "802.11 %p send probe "
+                                              "failed: %s\n", dev,
+                                              strerror ( rc ) );
                                }
                        }
                }
@@ -1158,7 +1163,7 @@ struct net80211_wlan * net80211_probe ( struct net80211_device *dev,
 
                if ( type != IEEE80211_STYPE_BEACON &&
                     type != IEEE80211_STYPE_PROBE_RESP ) {
-                       DBG2 ( "802.11 probe: non-beacon\n" );
+                       DBGC2 ( dev, "802.11 %p probe: non-beacon\n", dev );
                        goto drop;
                }
 
@@ -1170,28 +1175,31 @@ struct net80211_wlan * net80211_probe ( struct net80211_device *dev,
                }
                if ( ie_byte >= iob->tail ) {
                        /* didn't find an SSID */
-                       DBG2 ( "802.11 probe: beacon with no SSID\n" );
+                       DBGC2 ( dev, "802.11 %p probe: beacon with no SSID\n",
+                               dev );
                        goto drop;
                }
                if ( essid[0] && memcmp ( essid, ie->ssid, ie->len ) != 0 ) {
                        ie->ssid[ie->len] = 0;
-                       DBG2 ( "802.11 probe: beacon with wrong SSID (%s)\n",
-                              ie->ssid );
+                       DBGC2 ( dev, "802.11 %p probe: beacon with wrong SSID "
+                               "(%s)\n", dev, ie->ssid );
                        goto drop;
                }
 
                if ( ! wlan ) {
                        wlan = malloc ( sizeof ( *wlan ) );
                        if ( ! wlan ) {
-                               DBG ( "802.11 probe: out of memory\n" );
+                               DBGC ( dev, "802.11 %p probe: out of memory\n",
+                                      dev );
                                goto fail;
                        }
 
-                       DBGP ( "first good beacon:\n" );
+                       DBGP ( "802.11 %p first good beacon:\n", dev );
                        DBGP_HD ( iob->data, iob_len ( iob ) );
                } else if ( signal < wlan->signal ) {
-                       DBG ( "802.11 probe: discarding signal %d < %d\n",
-                             signal, wlan->signal );
+                       DBGC2 ( dev, "802.11 %p probe: beacon for %s (%s) with "
+                               "weaker signal %d\n", dev, ie->ssid,
+                               eth_ntoa ( hdr->addr3 ), signal );
                        goto drop;
                } else {
                        free_iob ( iob_disown ( wlan->beacon ) );
@@ -1204,8 +1212,9 @@ struct net80211_wlan * net80211_probe ( struct net80211_device *dev,
                wlan->beacon = iob;
                wlan->security = 0; /* XXX implement */
                wlan->channel = dev->channel;
-               DBG ( "802.11 probe: new best signal %d for AP %s on '%s'\n",
-                     wlan->signal, eth_ntoa ( wlan->bssid ), wlan->essid );
+               DBGC2 ( dev, "802.11 %p probe: beacon for %s (%s) with "
+                       "new best signal %d\n", dev, wlan->essid,
+                       eth_ntoa ( wlan->bssid ), wlan->signal );
 
                if ( currticks() > start_ticks + gather_timeout )
                        break;
@@ -1217,7 +1226,8 @@ struct net80211_wlan * net80211_probe ( struct net80211_device *dev,
        }
 
        if ( ! wlan )
-               DBG ( "802.11 probe: found no response for '%s'\n", essid );
+               DBGC ( dev, "802.11 %p probe: found no response for '%s'\n",
+                      dev, essid );
 
        free ( probe );
        net80211_keep_mgmt ( dev, old_keep );
@@ -1244,6 +1254,9 @@ void net80211_free_wlan ( struct net80211_wlan *wlan )
        }
 }
 
+#define ASSOC_TIMEOUT  TICKS_PER_SEC
+#define ASSOC_RETRIES  2
+
 /**
  * Step 802.11 association process
  *
@@ -1256,8 +1269,23 @@ static void net80211_step_associate ( struct process *proc )
        int rc = 0;
        int status = dev->state & NET80211_STATUS_MASK;
 
-       if ( dev->state & NET80211_WAITING )
-               return;
+       if ( dev->state & NET80211_WAITING ) {
+               if ( ! dev->associating )
+                       return;
+
+               if ( currticks() - dev->associating->last_packet > ASSOC_TIMEOUT ) {
+                       dev->associating->times_tried++;
+                       if ( ++dev->associating->times_tried > ASSOC_RETRIES ) {
+                               rc = -ETIMEDOUT;
+                               goto fail;
+                       }
+               } else {
+                       return;
+               }
+       } else {
+               if ( dev->associating )
+                       dev->associating->times_tried = 0;
+       }
 
        if ( ! dev->associating ) {
                /* state: scan */
@@ -1278,8 +1306,9 @@ static void net80211_step_associate ( struct process *proc )
                        goto fail;
                }
 
-               DBG ( "802.11 found network %s (%s)\n", dev->associating->essid,
-                     eth_ntoa ( dev->associating->bssid ) );
+               DBGC ( dev, "802.11 %p found network %s (%s)\n", dev,
+                      dev->associating->essid,
+                      eth_ntoa ( dev->associating->bssid ) );
 
                dev->associating->method = IEEE80211_AUTH_OPEN_SYSTEM;
                return;
@@ -1293,8 +1322,8 @@ static void net80211_step_associate ( struct process *proc )
                        /* we tried authenticating already, but failed */
 
                        if ( method == IEEE80211_AUTH_OPEN_SYSTEM &&
-                            ( status == IEEE80211_STATUS_AUTH_ALGO_UNSUPP ||
-                              status == IEEE80211_STATUS_AUTH_CHALL_INVALID ) ) {
+                            ( status == IEEE80211_STATUS_AUTH_CHALL_INVALID ||
+                              status == IEEE80211_STATUS_AUTH_ALGO_UNSUPP ) ) {
                                /* Maybe this network uses Shared Key? */
                                method = dev->associating->method =
                                        IEEE80211_AUTH_SHARED_KEY;
@@ -1304,7 +1333,10 @@ static void net80211_step_associate ( struct process *proc )
                        }
                }
 
-               DBG ( "802.11 authenticating with method %d\n", method );
+               DBGC ( dev, "802.11 %p authenticating with method %d\n", dev,
+                      method );
+
+               dev->associating->last_packet = currticks();
 
                rc = net80211_prepare ( dev, dev->associating );
                if ( rc )
@@ -1319,7 +1351,9 @@ static void net80211_step_associate ( struct process *proc )
 
        if ( ! ( dev->state & NET80211_ASSOCIATED ) ) {
                /* state: associate */
-               DBG ( "802.11 associating\n" );
+               DBGC ( dev, "802.11 %p associating\n", dev );
+
+               dev->associating->last_packet = currticks();
 
                if ( status != IEEE80211_STATUS_SUCCESS ) {
                        rc = E80211_STATUS ( status );
@@ -1335,6 +1369,10 @@ static void net80211_step_associate ( struct process *proc )
 
        if ( ! ( dev->state & NET80211_CRYPTO_SYNCED ) ) {
                /* state: crypto sync */
+               DBGC ( dev, "802.11 %p security handshaking\n", dev );
+
+               dev->associating->last_packet = currticks();
+
                dev->state |= NET80211_CRYPTO_SYNCED;
                /* XXX need to actually do something here once we
                   support WPA */
@@ -1342,17 +1380,18 @@ static void net80211_step_associate ( struct process *proc )
        }
 
        /* state: done! */
+       DBGC ( dev, "802.11 %p associated with %s (%s)\n", dev,
+              dev->essid, eth_ntoa ( dev->bssid ) );
+
        dev->netdev->state |= NETDEV_LINK_UP;
        dev->state &= ~NET80211_WORKING;
-       printf ( " ok, %s]\n", dev->essid );
        process_del ( proc );
        return;
 
  fail:
-       dev->state &= ~NET80211_WORKING;
-       DBG ( "802.11 association process failed with state=%04x "
-             "rc=%08x\n", dev->state, rc );
-       printf ( " error: %s]\n", strerror ( rc ) );
+       dev->state &= ~( NET80211_WORKING | NET80211_WAITING );
+       DBGC ( dev, "802.11 %p association failed (state=%04x): "
+              "%s\n", dev, dev->state, strerror ( rc ) );
        process_del ( proc );
 }
 
@@ -1379,8 +1418,9 @@ int net80211_check_ssid_update ( void )
                ssid[len] = 0;
 
                if ( strcmp ( ssid, dev->essid ) != 0 ) {
-                       DBG ( "802.11 updating association of %s: %s -> %s\n",
-                             dev->netdev->name, dev->essid, ssid );
+                       DBGC ( dev, "802.11 %p updating association: "
+                              "%s -> %s\n", dev, dev->essid, ssid );
+                       net80211_set_state ( dev, NET80211_AUTHENTICATED, 0, 0 );
                        net80211_autoassociate ( dev );
                }
        }
@@ -1399,10 +1439,8 @@ void net80211_autoassociate ( struct net80211_device *dev )
 {
        int len;
 
-       printf ( " [802.11 associating...");
-
        if ( ! ( dev->state & NET80211_WORKING ) ) {
-               DBG2 ( "802.11 spawning association process\n" );
+               DBGC2 ( dev, "802.11 %p spawning association process\n", dev );
                process_add ( &dev->proc_assoc );
        }
        
@@ -1413,8 +1451,8 @@ void net80211_autoassociate ( struct net80211_device *dev )
                              &net80211_ssid_setting, dev->essid,
                              IEEE80211_MAX_SSID_LEN );
        dev->essid[len] = 0;
-       dev->state |= NET80211_WORKING;
        dev->associating = NULL;
+       net80211_set_state ( dev, NET80211_ASSOCIATED, NET80211_WORKING, 0 );
 }
 
 /**
@@ -1499,14 +1537,16 @@ int net80211_prepare_default ( struct net80211_device *dev, int band,
                               int active )
 {
        if ( active && band != NET80211_BAND_2GHZ ) {
-               DBG ( "802.11 cannot perform active scanning on 5GHz band\n" );
+               DBGC ( dev, "802.11 %p cannot perform active scanning on "
+                      "5GHz band\n", dev );
                return -EINVAL_ACTIVE_SCAN;
        }
 
        if ( band == 0 ) {
                /* This can happen for a 5GHz-only card with 5GHz
                   scanning masked out by an active request. */
-               DBG ( "802.11 asked to prepare for scanning nothing\n" );
+               DBGC ( dev, "802.11 %p asked to prepare for scanning nothing\n",
+                      dev );
                return -EINVAL_ACTIVE_SCAN;
        }
 
@@ -1621,24 +1661,24 @@ static void net80211_handle_auth ( struct net80211_device *dev,
            ( struct ieee80211_auth * ) hdr->data;
 
        if ( auth->tx_seq & 1 ) {
-               DBG ( "%s: 802.11 authentication received improperly directed "
-                     "frame (seq. %d)\n", dev->netdev->name, auth->tx_seq );
+               DBGC ( dev, "802.11 %p authentication received improperly "
+                      "directed frame (seq. %d)\n", dev, auth->tx_seq );
                net80211_set_state ( dev, NET80211_WAITING, 0,
                                     IEEE80211_STATUS_FAILURE );
                return;
        }
 
        if ( auth->status != IEEE80211_STATUS_SUCCESS ) {
-               DBG ( "%s: 802.11 authentication failed: status %d\n",
-                     dev->netdev->name, auth->status );
+               DBGC ( dev, "802.11 %p authentication failed: status %d\n",
+                      dev, auth->status );
                net80211_set_state ( dev, NET80211_WAITING, 0,
                                     auth->status );
                return;
        }
 
        if ( auth->algorithm == IEEE80211_AUTH_SHARED_KEY && ! dev->crypto ) {
-               DBG ( "%s: 802.11 can't perform shared-key authentication without "
-                     "a cryptosystem\n", dev->netdev->name );
+               DBGC ( dev, "802.11 %p can't perform shared-key authentication "
+                      "without a cryptosystem\n", dev );
                net80211_set_state ( dev, NET80211_WAITING, 0,
                                     IEEE80211_STATUS_FAILURE );
                return;
@@ -1699,7 +1739,7 @@ int net80211_send_assoc ( struct net80211_device *dev,
        ie = net80211_marshal_request_info ( dev, assoc->info_element );
        ie_byte = ie;
 
-       DBGP ( "about to send assoc request:\n" );
+       DBGP ( "802.11 %p about to send association request:\n", dev );
        DBGP_HD ( iob->data, ie_byte - iob->data );
 
        /* XXX add RSN ie for WPA support */
@@ -1728,8 +1768,8 @@ static void net80211_handle_assoc_reply ( struct net80211_device *dev,
                              iob_len ( iob ) - sizeof ( *hdr ) );
 
        if ( assoc->status != IEEE80211_STATUS_SUCCESS ) {
-               DBG ( "%s: 802.11 association failed: status %d\n",
-                     dev->netdev->name, assoc->status );
+               DBGC ( dev, "802.11 %p association failed: status %d\n",
+                      dev, assoc->status );
                net80211_set_state ( dev, NET80211_WAITING, 0,
                                     assoc->status );
                return;
@@ -1770,15 +1810,15 @@ static void net80211_handle_mgmt ( struct net80211_device *dev,
                disassoc = ( struct ieee80211_disassoc * ) hdr->data;
                net80211_set_state ( dev, NET80211_AUTHENTICATED, 0,
                                     NET80211_IS_REASON | disassoc->reason );
-               DBG ( "%s: 802.11 deauthenticated: reason %d\n",
-                     dev->netdev->name, disassoc->reason );
+               DBGC ( dev, "802.11 %p deauthenticated: reason %d\n",
+                      dev, disassoc->reason );
                break;
        case IEEE80211_STYPE_DISASSOC:
                disassoc = ( struct ieee80211_disassoc * ) hdr->data;
                net80211_set_state ( dev, NET80211_ASSOCIATED, 0,
                                     NET80211_IS_REASON | disassoc->reason );
-               DBG ( "%s: 802.11 disassociated: reason %d\n",
-                     dev->netdev->name, disassoc->reason );
+               DBGC ( dev, "802.11 %p disassociated: reason %d\n",
+                     dev, disassoc->reason );
                break;
 
                /* We handle authentication and association. */
@@ -1802,7 +1842,7 @@ static void net80211_handle_mgmt ( struct net80211_device *dev,
                        struct net80211_rx_info *rxinf;
                        rxinf = zalloc ( sizeof ( *rxinf ) );
                        if ( ! rxinf ) {
-                               DBG ( "No memory for rxinf structure\n" );
+                               DBGC ( dev, "802.11 %p out of memory\n", dev );
                                break;
                        }
                        rxinf->signal = signal;
@@ -1820,12 +1860,13 @@ static void net80211_handle_mgmt ( struct net80211_device *dev,
        case IEEE80211_STYPE_ASSOC_REQ:
        case IEEE80211_STYPE_REASSOC_REQ:
                /* We should never receive these, only send them. */
-               DBG ( "Received strange management request (%04x)\n", stype );
+               DBGC ( dev, "802.11 %p received strange management request "
+                      "(%04x)\n", dev, stype );
                break;
 
        default:
-               DBG ( "Received unimplemented management packet (%04x)\n",
-                     stype );
+               DBGC ( dev, "802.11 %p received unimplemented management "
+                      "packet (%04x)\n", dev, stype );
                break;
        }
 
@@ -1956,8 +1997,8 @@ static void net80211_rx_frag ( struct net80211_device *dev,
                }
                if ( i == NET80211_NR_CONCURRENT_FRAGS ) {
                        /* drop non-first not-in-cache fragments */
-                       DBG2 ( "802.11 dropped fragment fc=%04x seq=%04x\n",
-                              hdr->fc, hdr->seq );
+                       DBGC ( dev, "802.11 %p dropped fragment fc=%04x "
+                              "seq=%04x\n", dev, hdr->fc, hdr->seq );
                        free_iob ( iob );
                        return;
                }
@@ -1979,9 +2020,10 @@ static void net80211_rx_frag ( struct net80211_device *dev,
                                net80211_free_frags ( dev, i );
                                net80211_rx ( dev, niob, signal );
                        } else {
-                               DBG ( "802.11 dropping fragmented packet due "
-                                     "to out-of-order arrival, fc=%04x "
-                                     "seq=%04x\n", hdr->fc, hdr->seq );
+                               DBGC ( dev, "802.11 %p dropping fragmented "
+                                      "packet due to out-of-order arrival, "
+                                      "fc=%04x seq=%04x\n", dev, hdr->fc,
+                                      hdr->seq );
                                net80211_free_frags ( dev, i );
                        }
                }
@@ -2051,8 +2093,8 @@ void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob,
        }
 
  drop:
-       DBG2 ( "802.11 dropped packet fc=%04x seq=%04x\n", hdr->fc,
-              hdr->seq );
+       DBGC2 ( dev, "802.11 %p dropped packet fc=%04x seq=%04x\n", dev,
+               hdr->fc, hdr->seq );
        free_iob ( iob );
        return;
 }