Main Page | Data Structures | Directories | File List | Data Fields | Globals

hostap_ap.c

Go to the documentation of this file.
00001 /*
00002  * Intersil Prism2 driver with Host AP (software access point) support
00003  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
00004  * <jkmaline@cc.hut.fi>
00005  * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
00006  *
00007  * This file is to be included into hostap.c when S/W AP functionality is
00008  * compiled.
00009  *
00010  * AP:  FIX:
00011  * - if unicast Class 2 (assoc,reassoc,disassoc) frame received from
00012  *   unauthenticated STA, send deauth. frame (8802.11: 5.5)
00013  * - if unicast Class 3 (data with to/from DS,deauth,pspoll) frame received
00014  *   from authenticated, but unassoc STA, send disassoc frame (8802.11: 5.5)
00015  * - if unicast Class 3 received from unauthenticated STA, send deauth. frame
00016  *   (8802.11: 5.5)
00017  */
00018 
00019 static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL,
00020                                                  DEF_INTS };
00021 MODULE_PARM(other_ap_policy, PARM_MIN_MAX "i");
00022 MODULE_PARM_DESC(other_ap_policy, "Other AP beacon monitoring policy (0-3)");
00023 
00024 static int ap_max_inactivity[MAX_PARM_DEVICES] = { AP_MAX_INACTIVITY_SEC,
00025                                                    DEF_INTS };
00026 MODULE_PARM(ap_max_inactivity, PARM_MIN_MAX "i");
00027 MODULE_PARM_DESC(ap_max_inactivity, "AP timeout (in seconds) for station "
00028                  "inactivity");
00029 
00030 static int ap_bridge_packets[MAX_PARM_DEVICES] = { 1, DEF_INTS };
00031 MODULE_PARM(ap_bridge_packets, PARM_MIN_MAX "i");
00032 MODULE_PARM_DESC(ap_bridge_packets, "Bridge packets directly between "
00033                  "stations");
00034 
00035 static int autom_ap_wds[MAX_PARM_DEVICES] = { 0, DEF_INTS };
00036 MODULE_PARM(autom_ap_wds, PARM_MIN_MAX "i");
00037 MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs "
00038                  "automatically");
00039 
00040 
00041 static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta);
00042 static void hostap_event_expired_sta(struct net_device *dev,
00043                                      struct sta_info *sta);
00044 static void handle_add_proc_queue(void *data);
00045 
00046 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00047 static void handle_wds_oper_queue(void *data);
00048 static void prism2_send_mgmt(struct net_device *dev,
00049                              int type, int subtype, char *body,
00050                              int body_len, int txevent, u8 *addr,
00051                              u16 tx_cb_idx);
00052 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00053 
00054 
00055 #ifndef PRISM2_NO_PROCFS_DEBUG
00056 static int ap_debug_proc_read(char *page, char **start, off_t off,
00057                               int count, int *eof, void *data)
00058 {
00059         char *p = page;
00060         struct ap_data *ap = (struct ap_data *) data;
00061 
00062         if (off != 0) {
00063                 *eof = 1;
00064                 return 0;
00065         }
00066 
00067         p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
00068         p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
00069         p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ);
00070         p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets);
00071         p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack);
00072         p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds);
00073         p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs);
00074 
00075         return (p - page);
00076 }
00077 #endif /* PRISM2_NO_PROCFS_DEBUG */
00078 
00079 
00080 static void ap_sta_hash_add(struct ap_data *ap, struct sta_info *sta)
00081 {
00082         sta->hnext = ap->sta_hash[STA_HASH(sta->addr)];
00083         ap->sta_hash[STA_HASH(sta->addr)] = sta;
00084 }
00085 
00086 static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta)
00087 {
00088         struct sta_info *s;
00089 
00090         s = ap->sta_hash[STA_HASH(sta->addr)];
00091         if (s == NULL) return;
00092         if (memcmp(s->addr, sta->addr, ETH_ALEN) == 0) {
00093                 ap->sta_hash[STA_HASH(sta->addr)] = s->hnext;
00094                 return;
00095         }
00096 
00097         while (s->hnext != NULL && memcmp(s->hnext->addr, sta->addr, ETH_ALEN)
00098                != 0)
00099                 s = s->hnext;
00100         if (s->hnext != NULL)
00101                 s->hnext = s->hnext->hnext;
00102         else
00103                 printk("AP: could not remove STA " MACSTR " from hash table\n",
00104                        MAC2STR(sta->addr));
00105 }
00106 
00107 static void ap_free_sta(struct ap_data *ap, struct sta_info *sta)
00108 {
00109         struct sk_buff *skb;
00110 
00111         if (sta->ap && sta->local)
00112                 hostap_event_expired_sta(sta->local->dev, sta);
00113 
00114         if (ap->proc != NULL) {
00115                 char name[20];
00116                 sprintf(name, MACSTR, MAC2STR(sta->addr));
00117                 remove_proc_entry(name, ap->proc);
00118         }
00119 
00120         if (sta->crypt) {
00121                 sta->crypt->ops->deinit(sta->crypt->priv);
00122                 kfree(sta->crypt);
00123                 sta->crypt = NULL;
00124         }
00125 
00126         while ((skb = skb_dequeue(&sta->tx_buf)) != NULL)
00127                 dev_kfree_skb(skb);
00128 
00129         ap->num_sta--;
00130 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00131         if (sta->aid > 0)
00132                 ap->sta_aid[sta->aid - 1] = NULL;
00133 
00134         if (!sta->ap && sta->u.sta.challenge)
00135                 kfree(sta->u.sta.challenge);
00136         del_timer(&sta->timer);
00137 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00138 
00139         kfree(sta);
00140 }
00141 
00142 
00143 struct set_tim_data {
00144         struct list_head list;
00145         int aid;
00146         int set;
00147 };
00148 
00149 static void hostap_set_tim(local_info_t *local, int aid, int set)
00150 {
00151         struct list_head *ptr;
00152         struct set_tim_data *new_entry;
00153 
00154         new_entry = (struct set_tim_data *)
00155                 kmalloc(sizeof(*new_entry), GFP_ATOMIC);
00156         if (new_entry == NULL) {
00157                 printk(KERN_DEBUG "%s: hostap_set_tim: kmalloc failed\n",
00158                        local->dev->name);
00159                 return;
00160         }
00161         memset(new_entry, 0, sizeof(*new_entry));
00162         new_entry->aid = aid;
00163         new_entry->set = set;
00164 
00165         spin_lock_bh(&local->ap->set_tim_lock);
00166         for (ptr = local->ap->set_tim_list.next;
00167              ptr != &local->ap->set_tim_list;
00168              ptr = ptr->next) {
00169                 struct set_tim_data *entry = (struct set_tim_data *) ptr;
00170                 if (entry->aid == aid) {
00171                         PDEBUG(DEBUG_PS2, "%s: hostap_set_tim: aid=%d "
00172                                "set=%d ==> %d\n",
00173                                local->dev->name, aid, entry->set, set);
00174                         entry->set = set;
00175                         kfree(new_entry);
00176                         new_entry = NULL;
00177                         break;
00178                 }
00179         }
00180         if (new_entry)
00181                 list_add_tail(&new_entry->list, &local->ap->set_tim_list);
00182         spin_unlock_bh(&local->ap->set_tim_lock);
00183 
00184         PRISM2_SCHEDULE_TASK(&local->ap->set_tim_queue);
00185 }
00186 
00187 
00188 static void handle_set_tim_queue(void *data)
00189 {
00190         local_info_t *local = (local_info_t *) data;
00191         struct set_tim_data *entry;
00192         u16 val;
00193 
00194         for (;;) {
00195                 entry = NULL;
00196                 spin_lock_bh(&local->ap->set_tim_lock);
00197                 if (!list_empty(&local->ap->set_tim_list)) {
00198                         entry = list_entry(local->ap->set_tim_list.next,
00199                                            struct set_tim_data, list);
00200                         list_del(&entry->list);
00201                 }
00202                 spin_unlock_bh(&local->ap->set_tim_lock);
00203                 if (!entry)
00204                         break;
00205 
00206                 PDEBUG(DEBUG_PS2, "%s: hostap_set_tim_queue: aid=%d set=%d\n",
00207                        local->dev->name, entry->aid, entry->set);
00208 
00209                 val = entry->aid;
00210                 if (entry->set)
00211                         val |= 0x8000;
00212                 if (hostap_set_word(local->dev, HFA384X_RID_CNFTIMCTRL, val)) {
00213                         printk(KERN_DEBUG "%s: set_tim failed (aid=%d "
00214                                "set=%d)\n",
00215                                local->dev->name, entry->aid, entry->set);
00216                 }
00217 
00218                 kfree(entry);
00219         }
00220 
00221 #ifndef NEW_MODULE_CODE
00222         MOD_DEC_USE_COUNT;
00223 #endif
00224 }
00225 
00226 
00227 static void hostap_event_new_sta(struct net_device *dev, struct sta_info *sta)
00228 {
00229 #if WIRELESS_EXT >= 15
00230         union iwreq_data wrqu;
00231         memset(&wrqu, 0, sizeof(wrqu));
00232         memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
00233         wrqu.addr.sa_family = ARPHRD_ETHER;
00234         wireless_send_event(dev, IWEVREGISTERED, &wrqu, NULL);
00235 #endif /* WIRELESS_EXT >= 15 */
00236 }
00237 
00238 
00239 static void hostap_event_expired_sta(struct net_device *dev,
00240                                      struct sta_info *sta)
00241 {
00242 #if WIRELESS_EXT >= 15
00243         union iwreq_data wrqu;
00244         memset(&wrqu, 0, sizeof(wrqu));
00245         memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
00246         wrqu.addr.sa_family = ARPHRD_ETHER;
00247         wireless_send_event(dev, IWEVEXPIRED, &wrqu, NULL);
00248 #endif /* WIRELESS_EXT >= 15 */
00249 }
00250 
00251 
00252 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00253 
00254 static void ap_handle_timer(unsigned long data)
00255 {
00256         struct sta_info *sta = (struct sta_info *) data;
00257         local_info_t *local;
00258         struct ap_data *ap;
00259         unsigned long next_time = 0;
00260         int was_assoc;
00261 
00262         if (sta == NULL || sta->local == NULL || sta->local->ap == NULL) {
00263                 PDEBUG(DEBUG_AP, "ap_handle_timer() called with NULL data\n");
00264                 return;
00265         }
00266 
00267         local = sta->local;
00268         ap = local->ap;
00269         was_assoc = sta->flags & WLAN_STA_ASSOC;
00270 
00271         if (atomic_read(&sta->users) != 0)
00272                 next_time = jiffies + HZ;
00273         else if ((sta->flags & WLAN_STA_PERM) && !(sta->flags & WLAN_STA_AUTH))
00274                 next_time = jiffies + ap->max_inactivity;
00275 
00276         if (time_before(jiffies, sta->last_rx + ap->max_inactivity)) {
00277                 /* station activity detected; reset timeout state */
00278                 sta->timeout_next = STA_NULLFUNC;
00279                 next_time = sta->last_rx + ap->max_inactivity;
00280         } else if (sta->timeout_next == STA_DISASSOC &&
00281                    !(sta->flags & WLAN_STA_PENDING_POLL)) {
00282                 /* STA ACKed data nullfunc frame poll */
00283                 sta->timeout_next = STA_NULLFUNC;
00284                 next_time = jiffies + ap->max_inactivity;
00285         }
00286 
00287         if (next_time) {
00288                 sta->timer.expires = next_time;
00289                 add_timer(&sta->timer);
00290                 return;
00291         }
00292 
00293         if (sta->ap)
00294                 sta->timeout_next = STA_DEAUTH;
00295 
00296         if (sta->timeout_next == STA_DEAUTH && !(sta->flags & WLAN_STA_PERM)) {
00297                 spin_lock(&ap->sta_table_lock);
00298                 ap_sta_hash_del(ap, sta);
00299                 list_del(&sta->list);
00300                 spin_unlock(&ap->sta_table_lock);
00301                 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
00302         } else if (sta->timeout_next == STA_DISASSOC)
00303                 sta->flags &= ~WLAN_STA_ASSOC;
00304 
00305         if (was_assoc && !(sta->flags & WLAN_STA_ASSOC) && !sta->ap)
00306                 hostap_event_expired_sta(local->dev, sta);
00307 
00308         if (sta->timeout_next == STA_DEAUTH && sta->aid > 0 &&
00309             !skb_queue_empty(&sta->tx_buf)) {
00310                 hostap_set_tim(local, sta->aid, 0);
00311                 sta->flags &= ~WLAN_STA_TIM;
00312         }
00313 
00314         if (sta->ap) {
00315                 if (ap->autom_ap_wds) {
00316                         PDEBUG(DEBUG_AP, "%s: removing automatic WDS "
00317                                "connection to AP " MACSTR "\n",
00318                                local->dev->name, MAC2STR(sta->addr));
00319                         hostap_wds_link_oper(local, sta->addr, WDS_DEL);
00320                 }
00321         } else if (sta->timeout_next == STA_NULLFUNC) {
00322                 /* send data frame to poll STA and check whether this frame
00323                  * is ACKed */
00324                 /* FIX: WLAN_FC_STYPE_NULLFUNC would be more appropriate, but
00325                  * it is apparently not retried so TX Exc events are not
00326                  * received for it */
00327                 sta->flags |= WLAN_STA_PENDING_POLL;
00328                 prism2_send_mgmt(local->dev, WLAN_FC_TYPE_DATA,
00329                                  WLAN_FC_STYPE_DATA, NULL, 0, 1,
00330                                  sta->addr, ap->tx_callback_poll);
00331         } else {
00332                 int deauth = sta->timeout_next == STA_DEAUTH;
00333                 u16 resp;
00334                 PDEBUG(DEBUG_AP, "%s: sending %s info to STA " MACSTR
00335                        "(last=%lu, jiffies=%lu)\n",
00336                        local->dev->name,
00337                        deauth ? "deauthentication" : "disassociation",
00338                        MAC2STR(sta->addr), sta->last_rx, jiffies);
00339 
00340                 resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID :
00341                                    WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
00342                 prism2_send_mgmt(local->dev, WLAN_FC_TYPE_MGMT,
00343                                  (deauth ? WLAN_FC_STYPE_DEAUTH :
00344                                   WLAN_FC_STYPE_DISASSOC),
00345                                  (char *) &resp, 2, 1, sta->addr, 0);
00346         }
00347 
00348         if (sta->timeout_next == STA_DEAUTH) {
00349                 if (sta->flags & WLAN_STA_PERM) {
00350                         PDEBUG(DEBUG_AP, "%s: STA " MACSTR " would have been "
00351                                "removed, but it has 'perm' flag\n",
00352                                local->dev->name, MAC2STR(sta->addr));
00353                 } else
00354                         ap_free_sta(ap, sta);
00355                 return;
00356         }
00357 
00358         if (sta->timeout_next == STA_NULLFUNC) {
00359                 sta->timeout_next = STA_DISASSOC;
00360                 sta->timer.expires = jiffies + AP_DISASSOC_DELAY;
00361         } else {
00362                 sta->timeout_next = STA_DEAUTH;
00363                 sta->timer.expires = jiffies + AP_DEAUTH_DELAY;
00364         }
00365 
00366         add_timer(&sta->timer);
00367 }
00368 
00369 
00370 void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
00371                             int resend)
00372 {
00373         u8 addr[ETH_ALEN];
00374         u16 resp;
00375         int i;
00376 
00377         PDEBUG(DEBUG_AP, "%s: Deauthenticate all stations\n", dev->name);
00378         memset(addr, 0xff, ETH_ALEN);
00379 
00380         resp = __constant_cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
00381 
00382         /* deauth message sent; try to resend it few times; the message is
00383          * broadcast, so it may be delayed until next DTIM; there is not much
00384          * else we can do at this point since the driver is going to be shut
00385          * down */
00386         for (i = 0; i < 5; i++) {
00387                 prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH,
00388                                  (char *) &resp, 2, 1, addr, 0);
00389 
00390                 if (!resend || ap->num_sta <= 0)
00391                         return;
00392 
00393                 mdelay(50);
00394         }
00395 }
00396 
00397 
00398 static int ap_control_proc_read(char *page, char **start, off_t off,
00399                                 int count, int *eof, void *data)
00400 {
00401         char *p = page;
00402         struct ap_data *ap = (struct ap_data *) data;
00403         char *policy_txt;
00404         struct list_head *ptr;
00405         struct mac_entry *entry;
00406 
00407         if (off != 0) {
00408                 *eof = 1;
00409                 return 0;
00410         }
00411 
00412         switch (ap->mac_restrictions.policy) {
00413         case MAC_POLICY_OPEN:
00414                 policy_txt = "open";
00415                 break;
00416         case MAC_POLICY_ALLOW:
00417                 policy_txt = "allow";
00418                 break;
00419         case MAC_POLICY_DENY:
00420                 policy_txt = "deny";
00421                 break;
00422         default:
00423                 policy_txt = "unknown";
00424                 break;
00425         };
00426         p += sprintf(p, "MAC policy: %s\n", policy_txt);
00427         p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
00428         p += sprintf(p, "MAC list:\n");
00429         spin_lock_bh(&ap->mac_restrictions.lock);
00430         for (ptr = ap->mac_restrictions.mac_list.next;
00431              ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) {
00432                 if (p - page > PAGE_SIZE - 80) {
00433                         p += sprintf(p, "All entries did not fit one page.\n");
00434                         break;
00435                 }
00436 
00437                 entry = list_entry(ptr, struct mac_entry, list);
00438                 p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr));
00439         }
00440         spin_unlock_bh(&ap->mac_restrictions.lock);
00441 
00442         return (p - page);
00443 }
00444 
00445 
00446 static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
00447                               u8 *mac)
00448 {
00449         struct mac_entry *entry;
00450 
00451         entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL);
00452         if (entry == NULL)
00453                 return -1;
00454 
00455         memcpy(entry->addr, mac, ETH_ALEN);
00456 
00457         spin_lock_bh(&mac_restrictions->lock);
00458         list_add_tail(&entry->list, &mac_restrictions->mac_list);
00459         mac_restrictions->entries++;
00460         spin_unlock_bh(&mac_restrictions->lock);
00461 
00462         return 0;
00463 }
00464 
00465 
00466 static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
00467                               u8 *mac)
00468 {
00469         struct list_head *ptr;
00470         struct mac_entry *entry;
00471 
00472         spin_lock_bh(&mac_restrictions->lock);
00473         for (ptr = mac_restrictions->mac_list.next;
00474              ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
00475                 entry = list_entry(ptr, struct mac_entry, list);
00476 
00477                 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
00478                         list_del(ptr);
00479                         kfree(entry);
00480                         mac_restrictions->entries--;
00481                         spin_unlock_bh(&mac_restrictions->lock);
00482                         return 0;
00483                 }
00484         }
00485         spin_unlock_bh(&mac_restrictions->lock);
00486         return -1;
00487 }
00488 
00489 
00490 static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
00491                                u8 *mac)
00492 {
00493         struct list_head *ptr;
00494         struct mac_entry *entry;
00495         int found = 0;
00496 
00497         if (mac_restrictions->policy == MAC_POLICY_OPEN)
00498                 return 0;
00499 
00500         spin_lock_bh(&mac_restrictions->lock);
00501         for (ptr = mac_restrictions->mac_list.next;
00502              ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
00503                 entry = list_entry(ptr, struct mac_entry, list);
00504 
00505                 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
00506                         found = 1;
00507                         break;
00508                 }
00509         }
00510         spin_unlock_bh(&mac_restrictions->lock);
00511 
00512         if (mac_restrictions->policy == MAC_POLICY_ALLOW)
00513                 return !found;
00514         else
00515                 return found;
00516 }
00517 
00518 
00519 static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
00520 {
00521         struct list_head *ptr, *n;
00522         struct mac_entry *entry;
00523 
00524         if (mac_restrictions->entries == 0)
00525                 return;
00526 
00527         spin_lock_bh(&mac_restrictions->lock);
00528         for (ptr = mac_restrictions->mac_list.next, n = ptr->next;
00529              ptr != &mac_restrictions->mac_list;
00530              ptr = n, n = ptr->next) {
00531                 entry = list_entry(ptr, struct mac_entry, list);
00532                 list_del(ptr);
00533                 kfree(entry);
00534         }
00535         mac_restrictions->entries = 0;
00536         spin_unlock_bh(&mac_restrictions->lock);
00537 }
00538 
00539 
00540 static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
00541                                u8 *mac)
00542 {
00543         struct sta_info *sta;
00544         u16 resp;
00545 
00546         spin_lock_bh(&ap->sta_table_lock);
00547         sta = ap_get_sta(ap, mac);
00548         if (sta) {
00549                 ap_sta_hash_del(ap, sta);
00550                 list_del(&sta->list);
00551         }
00552         spin_unlock_bh(&ap->sta_table_lock);
00553 
00554         if (!sta)
00555                 return -EINVAL;
00556 
00557         resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
00558         prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH,
00559                          (char *) &resp, 2, 1, sta->addr, 0);
00560 
00561         if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
00562                 hostap_event_expired_sta(dev, sta);
00563 
00564         ap_free_sta(ap, sta);
00565 
00566         return 0;
00567 }
00568 
00569 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00570 
00571 
00572 static void ap_control_kickall(struct ap_data *ap)
00573 {
00574         struct list_head *ptr, *n;
00575         struct sta_info *sta;
00576   
00577         spin_lock_bh(&ap->sta_table_lock);
00578         for (ptr = ap->sta_list.next, n = ptr->next; ptr != &ap->sta_list;
00579              ptr = n, n = ptr->next) {
00580                 sta = list_entry(ptr, struct sta_info, list);
00581                 ap_sta_hash_del(ap, sta);
00582                 list_del(&sta->list);
00583                 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
00584                         hostap_event_expired_sta(sta->local->dev, sta);
00585                 ap_free_sta(ap, sta);
00586         }
00587         spin_unlock_bh(&ap->sta_table_lock);
00588 }
00589 
00590 
00591 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00592 
00593 #define PROC_LIMIT (PAGE_SIZE - 80)
00594 
00595 static int prism2_ap_proc_read(char *page, char **start, off_t off,
00596                                int count, int *eof, void *data)
00597 {
00598         char *p = page;
00599         struct ap_data *ap = (struct ap_data *) data;
00600         struct list_head *ptr;
00601         int i;
00602 
00603         if (off > PROC_LIMIT) {
00604                 *eof = 1;
00605                 return 0;
00606         }
00607 
00608         p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
00609         spin_lock_bh(&ap->sta_table_lock);
00610         for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
00611                 struct sta_info *sta = (struct sta_info *) ptr;
00612 
00613                 if (!sta->ap)
00614                         continue;
00615 
00616                 p += sprintf(p, MACSTR " %d %d %d %d '", MAC2STR(sta->addr),
00617                              sta->u.ap.channel, sta->last_rx_signal,
00618                              sta->last_rx_silence, sta->last_rx_rate);
00619                 for (i = 0; i < sta->u.ap.ssid_len; i++)
00620                         p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
00621                                           sta->u.ap.ssid[i] < 127) ?
00622                                          "%c" : "<%02x>"),
00623                                      sta->u.ap.ssid[i]);
00624                 p += sprintf(p, "'");
00625                 if (sta->capability & WLAN_CAPABILITY_ESS)
00626                         p += sprintf(p, " [ESS]");
00627                 if (sta->capability & WLAN_CAPABILITY_IBSS)
00628                         p += sprintf(p, " [IBSS]");
00629                 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
00630                         p += sprintf(p, " [WEP]");
00631                 p += sprintf(p, "\n");
00632 
00633                 if ((p - page) > PROC_LIMIT) {
00634                         printk(KERN_DEBUG "hostap: ap proc did not fit\n");
00635                         break;
00636                 }
00637         }
00638         spin_unlock_bh(&ap->sta_table_lock);
00639 
00640         if ((p - page) <= off) {
00641                 *eof = 1;
00642                 return 0;
00643         }
00644 
00645         *start = page + off;
00646 
00647         return (p - page - off);
00648 }
00649 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00650 
00651 
00652 void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver)
00653 {
00654         if (!ap)
00655                 return;
00656 
00657         if (sta_fw_ver == PRISM2_FW_VER(0,8,0)) {
00658                 PDEBUG(DEBUG_AP, "Using data::nullfunc ACK workaround - "
00659                        "firmware upgrade recommended\n");
00660                 ap->nullfunc_ack = 1;
00661         } else
00662                 ap->nullfunc_ack = 0;
00663 
00664         if (sta_fw_ver == PRISM2_FW_VER(1,4,2)) {
00665                 printk(KERN_WARNING "%s: Warning: secondary station firmware "
00666                        "version 1.4.2 does not seem to work in Host AP mode\n",
00667                        ap->local->dev->name);
00668         }
00669 }
00670 
00671 
00672 /* Called only as a tasklet (software IRQ) */
00673 static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
00674 {
00675         struct ap_data *ap = data;
00676         u16 fc;
00677         struct hostap_ieee80211_hdr *hdr;
00678 
00679         if (!ap->local->hostapd || !ap->local->apdev) {
00680                 dev_kfree_skb(skb);
00681                 return;
00682         }
00683 
00684         hdr = (struct hostap_ieee80211_hdr *) skb->data;
00685         fc = le16_to_cpu(hdr->frame_control);
00686 
00687         /* Pass the TX callback frame to the hostapd; use 802.11 header version
00688          * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */
00689 
00690         fc &= ~WLAN_FC_PVER;
00691         fc |= ok ? BIT(1) : BIT(0);
00692         hdr->frame_control = cpu_to_le16(fc);
00693 
00694         skb->dev = ap->local->apdev;
00695         skb_pull(skb, hostap_80211_get_hdrlen(fc));
00696         skb->pkt_type = PACKET_OTHERHOST;
00697         skb->protocol = __constant_htons(ETH_P_802_2);
00698         memset(skb->cb, 0, sizeof(skb->cb));
00699         netif_rx(skb);
00700 }
00701 
00702 
00703 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00704 /* Called only as a tasklet (software IRQ) */
00705 static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
00706 {
00707         struct ap_data *ap = data;
00708         struct net_device *dev = ap->local->dev;
00709         struct hostap_ieee80211_hdr *hdr;
00710         u16 fc, *pos, auth_alg, auth_transaction, status;
00711         struct sta_info *sta = NULL;
00712         char *txt = NULL;
00713 
00714         if (ap->local->hostapd) {
00715                 dev_kfree_skb(skb);
00716                 return;
00717         }
00718 
00719         hdr = (struct hostap_ieee80211_hdr *) skb->data;
00720         fc = le16_to_cpu(hdr->frame_control);
00721         if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
00722             WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_AUTH ||
00723             skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
00724                 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
00725                        "frame\n", dev->name);
00726                 dev_kfree_skb(skb);
00727                 return;
00728         }
00729 
00730         if (!ok) {
00731                 txt = "frame was not ACKed";
00732                 goto done;
00733         }
00734 
00735         spin_lock(&ap->sta_table_lock);
00736         sta = ap_get_sta(ap, hdr->addr1);
00737         if (sta)
00738                 atomic_inc(&sta->users);
00739         spin_unlock(&ap->sta_table_lock);
00740 
00741         if (!sta) {
00742                 txt = "STA not found";
00743                 goto done;
00744         }
00745 
00746         pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
00747         auth_alg = le16_to_cpu(*pos++);
00748         auth_transaction = le16_to_cpu(*pos++);
00749         status = le16_to_cpu(*pos++);
00750         if (status == WLAN_STATUS_SUCCESS &&
00751             ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
00752              (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
00753                 txt = "STA authenticated";
00754                 sta->flags |= WLAN_STA_AUTH;
00755                 sta->last_auth = jiffies;
00756         } else if (status != WLAN_STATUS_SUCCESS)
00757                 txt = "authentication failed";
00758 
00759  done:
00760         if (sta)
00761                 atomic_dec(&sta->users);
00762         if (txt) {
00763                 PDEBUG(DEBUG_AP, "%s: " MACSTR " auth_cb - %s\n",
00764                        dev->name, MAC2STR(hdr->addr1), txt);
00765         }
00766         dev_kfree_skb(skb);
00767 }
00768 
00769 
00770 /* Called only as a tasklet (software IRQ) */
00771 static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
00772 {
00773         struct ap_data *ap = data;
00774         struct net_device *dev = ap->local->dev;
00775         struct hostap_ieee80211_hdr *hdr;
00776         u16 fc, *pos, status;
00777         struct sta_info *sta = NULL;
00778         char *txt = NULL;
00779 
00780         if (ap->local->hostapd) {
00781                 dev_kfree_skb(skb);
00782                 return;
00783         }
00784 
00785         hdr = (struct hostap_ieee80211_hdr *) skb->data;
00786         fc = le16_to_cpu(hdr->frame_control);
00787         if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
00788             (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ASSOC_RESP &&
00789              WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_REASSOC_RESP) ||
00790             skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
00791                 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
00792                        "frame\n", dev->name);
00793                 dev_kfree_skb(skb);
00794                 return;
00795         }
00796 
00797         if (!ok) {
00798                 txt = "frame was not ACKed";
00799                 goto done;
00800         }
00801 
00802         spin_lock(&ap->sta_table_lock);
00803         sta = ap_get_sta(ap, hdr->addr1);
00804         if (sta)
00805                 atomic_inc(&sta->users);
00806         spin_unlock(&ap->sta_table_lock);
00807 
00808         if (!sta) {
00809                 txt = "STA not found";
00810                 goto done;
00811         }
00812 
00813         pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
00814         pos++;
00815         status = le16_to_cpu(*pos++);
00816         if (status == WLAN_STATUS_SUCCESS) {
00817                 if (!(sta->flags & WLAN_STA_ASSOC))
00818                         hostap_event_new_sta(dev, sta);
00819                 txt = "STA associated";
00820                 sta->flags |= WLAN_STA_ASSOC;
00821                 sta->last_assoc = jiffies;
00822         } else
00823                 txt = "association failed";
00824 
00825  done:
00826         if (sta)
00827                 atomic_dec(&sta->users);
00828         if (txt) {
00829                 PDEBUG(DEBUG_AP, "%s: " MACSTR " assoc_cb - %s\n",
00830                        dev->name, MAC2STR(hdr->addr1), txt);
00831         }
00832         dev_kfree_skb(skb);
00833 }
00834 
00835 /* Called only as a tasklet (software IRQ); TX callback for poll frames used
00836  * in verifying whether the STA is still present. */
00837 static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
00838 {
00839         struct ap_data *ap = data;
00840         struct net_device *dev = ap->local->dev;
00841         struct hostap_ieee80211_hdr *hdr;
00842         struct sta_info *sta;
00843 
00844         if (skb->len < 24)
00845                 goto fail;
00846         hdr = (struct hostap_ieee80211_hdr *) skb->data;
00847         if (ok) {
00848                 spin_lock(&ap->sta_table_lock);
00849                 sta = ap_get_sta(ap, hdr->addr1);
00850                 if (sta)
00851                         sta->flags &= ~WLAN_STA_PENDING_POLL;
00852                 spin_unlock(&ap->sta_table_lock);
00853         } else {
00854                 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " did not ACK activity "
00855                        "poll frame\n", dev->name, MAC2STR(hdr->addr1));
00856         }
00857 
00858  fail:
00859         dev_kfree_skb(skb);
00860 }
00861 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00862 
00863 
00864 void hostap_init_data(local_info_t *local)
00865 {
00866         struct ap_data *ap = local->ap;
00867 
00868         if (ap == NULL) {
00869                 printk(KERN_WARNING "hostap_init_data: ap == NULL\n");
00870                 return;
00871         }
00872         memset(ap, 0, sizeof(struct ap_data));
00873         ap->local = local;
00874 
00875         ap->ap_policy = GET_INT_PARM(other_ap_policy, local->card_idx);
00876         ap->proc = local->proc;
00877         ap->bridge_packets = GET_INT_PARM(ap_bridge_packets, local->card_idx);
00878         ap->max_inactivity =
00879                 GET_INT_PARM(ap_max_inactivity, local->card_idx) * HZ;
00880         ap->autom_ap_wds = GET_INT_PARM(autom_ap_wds, local->card_idx);
00881 
00882         spin_lock_init(&ap->sta_table_lock);
00883         INIT_LIST_HEAD(&ap->sta_list);
00884 
00885 #ifndef PRISM2_NO_PROCFS_DEBUG
00886         if (ap->proc != NULL) {
00887                 create_proc_read_entry("ap_debug", 0, ap->proc,
00888                                        ap_debug_proc_read, ap);
00889         }
00890 #endif /* PRISM2_NO_PROCFS_DEBUG */
00891 
00892         /* Initialize task queue structure for AP management */
00893         INIT_WORK(&local->ap->set_tim_queue, handle_set_tim_queue, local);
00894         INIT_LIST_HEAD(&ap->set_tim_list);
00895         spin_lock_init(&ap->set_tim_lock);
00896 
00897         INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap);
00898 
00899         ap->tx_callback_idx =
00900                 hostap_tx_callback_register(local, hostap_ap_tx_cb, ap);
00901         if (ap->tx_callback_idx == 0)
00902                 printk(KERN_WARNING "%s: failed to register TX callback for "
00903                        "AP\n", local->dev->name);
00904 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00905         INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local);
00906 
00907         ap->tx_callback_auth =
00908                 hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap);
00909         ap->tx_callback_assoc =
00910                 hostap_tx_callback_register(local, hostap_ap_tx_cb_assoc, ap);
00911         ap->tx_callback_poll =
00912                 hostap_tx_callback_register(local, hostap_ap_tx_cb_poll, ap);
00913         if (ap->tx_callback_auth == 0 || ap->tx_callback_assoc == 0 ||
00914                 ap->tx_callback_poll == 0)
00915                 printk(KERN_WARNING "%s: failed to register TX callback for "
00916                        "AP\n", local->dev->name);
00917 
00918         spin_lock_init(&ap->mac_restrictions.lock);
00919         INIT_LIST_HEAD(&ap->mac_restrictions.mac_list);
00920         if (ap->proc != NULL) {
00921                 create_proc_read_entry("ap_control", 0, ap->proc,
00922                                        ap_control_proc_read, ap);
00923         }
00924 
00925         create_proc_read_entry("ap", 0, ap->proc,
00926                                prism2_ap_proc_read, ap);
00927 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00928 
00929         ap->initialized = 1;
00930 }
00931 
00932 void hostap_free_data(struct ap_data *ap)
00933 {
00934         struct list_head *ptr, *n;
00935 
00936         if (ap == NULL || !ap->initialized) {
00937                 printk(KERN_DEBUG "hostap_free_data: ap has not yet been "
00938                        "initialized - skip resource freeing\n");
00939                 return;
00940         }
00941 
00942 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00943         if (ap->crypt)
00944                 ap->crypt->deinit(ap->crypt_priv);
00945         ap->crypt = ap->crypt_priv = NULL;
00946 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00947 
00948         ptr = ap->sta_list.next;
00949         while (ptr != NULL && ptr != &ap->sta_list) {
00950                 struct sta_info *sta = (struct sta_info *) ptr;
00951                 ptr = ptr->next;
00952                 ap_sta_hash_del(ap, sta);
00953                 list_del(&sta->list);
00954                 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
00955                         hostap_event_expired_sta(sta->local->dev, sta);
00956                 ap_free_sta(ap, sta);
00957         }
00958 
00959         for (ptr = ap->set_tim_list.next, n = ptr->next;
00960              ptr != &ap->set_tim_list; ptr = n, n = ptr->next) {
00961                 struct set_tim_data *entry;
00962                 entry = list_entry(ptr, struct set_tim_data, list);
00963                 list_del(&entry->list);
00964                 kfree(entry);
00965         }
00966 
00967 #ifndef PRISM2_NO_PROCFS_DEBUG
00968         if (ap->proc != NULL) {
00969                 remove_proc_entry("ap_debug", ap->proc);
00970         }
00971 #endif /* PRISM2_NO_PROCFS_DEBUG */
00972 
00973 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00974         if (ap->proc != NULL) {
00975           remove_proc_entry("ap", ap->proc);
00976                 remove_proc_entry("ap_control", ap->proc);
00977         }
00978         ap_control_flush_macs(&ap->mac_restrictions);
00979 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
00980 
00981         ap->initialized = 0;
00982 }
00983 
00984 
00985 /* caller should have mutex for AP STA list handling */
00986 static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta)
00987 {
00988         struct sta_info *s;
00989 
00990         s = ap->sta_hash[STA_HASH(sta)];
00991         while (s != NULL && memcmp(s->addr, sta, ETH_ALEN) != 0)
00992                 s = s->hnext;
00993         return s;
00994 }
00995 
00996 
00997 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
00998 
00999 /* Called from timer handler and from scheduled AP queue handlers */
01000 static void prism2_send_mgmt(struct net_device *dev,
01001                              int type, int subtype, char *body,
01002                              int body_len, int txevent, u8 *addr,
01003                              u16 tx_cb_idx)
01004 {
01005         struct hostap_interface *iface = dev->priv;
01006         local_info_t *local = iface->local;
01007         struct hfa384x_tx_frame *txdesc;
01008         u16 fc, tx_control;
01009         struct sk_buff *skb;
01010 
01011         if (!(dev->flags & IFF_UP)) {
01012                 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt - device is not UP - "
01013                        "cannot send frame\n", dev->name);
01014                 return;
01015         }
01016 
01017         skb = dev_alloc_skb(sizeof(*txdesc) + body_len);
01018         if (skb == NULL) {
01019                 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt failed to allocate "
01020                        "skb\n", dev->name);
01021                 return;
01022         }
01023 
01024         txdesc = (struct hfa384x_tx_frame *) skb_put(skb, sizeof(*txdesc));
01025         if (body)
01026                 memcpy(skb_put(skb, body_len), body, body_len);
01027 
01028         memset(txdesc, 0, sizeof(*txdesc));
01029         /* FIX: set tx_rate if f/w does not know how to do it */
01030         tx_control = txevent ? local->tx_control : HFA384X_TX_CTRL_802_11;
01031         if (tx_cb_idx)
01032                 tx_control |= HFA384X_TX_CTRL_TX_OK;
01033         txdesc->sw_support = cpu_to_le16(tx_cb_idx);
01034         txdesc->tx_control = cpu_to_le16(tx_control);
01035         txdesc->data_len = cpu_to_le16(body_len);
01036 
01037         fc = (type << 2) | (subtype << 4);
01038 
01039         memcpy(txdesc->addr1, addr, ETH_ALEN); /* DA / RA */
01040         if (type == WLAN_FC_TYPE_DATA) {
01041                 fc |= WLAN_FC_FROMDS;
01042                 memcpy(txdesc->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
01043                 memcpy(txdesc->addr3, dev->dev_addr, ETH_ALEN); /* SA */
01044         } else if (type == WLAN_FC_TYPE_CTRL) {
01045                 /* control:ACK does not have addr2 or addr3 */
01046                 memset(txdesc->addr2, 0, ETH_ALEN);
01047                 memset(txdesc->addr3, 0, ETH_ALEN);
01048         } else {
01049                 memcpy(txdesc->addr2, dev->dev_addr, ETH_ALEN); /* SA */
01050                 memcpy(txdesc->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
01051         }
01052 
01053         txdesc->frame_control = cpu_to_le16(fc);
01054 
01055         /* FIX: is it OK to call dev_queue_xmit() here? This can be called in
01056          * interrupt context, but not in hard interrupt (like prism2_rx() that
01057          * required bridge_list. If needed, bridge_list could be used also here
01058          * when prism2_send_mgmt is called in interrupt context. */
01059 
01060         skb->protocol = __constant_htons(ETH_P_HOSTAP);
01061         skb->dev = dev;
01062         skb->mac.raw = skb->nh.raw = skb->data;
01063         dev_queue_xmit(skb);
01064 }
01065 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
01066 
01067 
01068 static int prism2_sta_proc_read(char *page, char **start, off_t off,
01069                                 int count, int *eof, void *data)
01070 {
01071         char *p = page;
01072         struct sta_info *sta = (struct sta_info *) data;
01073         int i;
01074 
01075         /* FIX: possible race condition.. the STA data could have just expired,
01076          * but proc entry was still here so that the read could have started;
01077          * some locking should be done here.. */
01078 
01079         if (off != 0) {
01080                 *eof = 1;
01081                 return 0;
01082         }
01083 
01084         p += sprintf(p, "%s=" MACSTR "\nusers=%d\naid=%d\n"
01085                      "flags=0x%04x%s%s%s%s%s%s%s\n"
01086                      "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
01087                      sta->ap ? "AP" : "STA",
01088                      MAC2STR(sta->addr), atomic_read(&sta->users), sta->aid,
01089                      sta->flags,
01090                      sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
01091                      sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
01092                      sta->flags & WLAN_STA_PS ? " PS" : "",
01093                      sta->flags & WLAN_STA_TIM ? " TIM" : "",
01094                      sta->flags & WLAN_STA_PERM ? " PERM" : "",
01095                      sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
01096                      sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
01097                      sta->capability, sta->listen_interval);
01098         /* supported_rates: 500 kbit/s units with msb ignored */
01099         for (i = 0; i < sizeof(sta->supported_rates); i++)
01100                 if (sta->supported_rates[i] != 0)
01101                         p += sprintf(p, "%d%sMbps ",
01102                                      (sta->supported_rates[i] & 0x7f) / 2,
01103                                      sta->supported_rates[i] & 1 ? ".5" : "");
01104         p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
01105                      "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
01106                      "tx_packets=%lu\n"
01107                      "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
01108                      "last_rx: silence=%d signal=%d rate=%d\n"
01109                      "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
01110                      "tx[11M]=%d\n"
01111                      "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
01112                      jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
01113                      sta->last_tx,
01114                      sta->rx_packets, sta->tx_packets, sta->rx_bytes,
01115                      sta->tx_bytes, skb_queue_len(&sta->tx_buf),
01116                      sta->last_rx_silence,
01117                      sta->last_rx_signal, sta->last_rx_rate,
01118                      sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
01119                      sta->tx_count[2], sta->tx_count[3],  sta->rx_count[0],
01120                      sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
01121         if (sta->crypt && sta->crypt->ops)
01122                 p += sprintf(p, "crypt=%s\n", sta->crypt->ops->name);
01123 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
01124         if (sta->ap) {
01125                 if (sta->u.ap.channel >= 0)
01126                         p += sprintf(p, "channel=%d\n", sta->u.ap.channel);
01127                 p += sprintf(p, "ssid=");
01128                 for (i = 0; i < sta->u.ap.ssid_len; i++)
01129                         p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
01130                                           sta->u.ap.ssid[i] < 127) ?
01131                                          "%c" : "<%02x>"),
01132                                      sta->u.ap.ssid[i]);
01133                 p += sprintf(p, "\n");
01134         }
01135 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
01136 
01137         return (p - page);
01138 }
01139 
01140 
01141 static void handle_add_proc_queue(void *data)
01142 {
01143         struct ap_data *ap = (struct ap_data *) data;
01144         struct sta_info *sta;
01145         char name[20];
01146         struct add_sta_proc_data *entry, *prev;
01147 
01148         entry = ap->add_sta_proc_entries;
01149         ap->add_sta_proc_entries = NULL;
01150 
01151         while (entry) {
01152                 spin_lock_bh(&ap->sta_table_lock);
01153                 sta = ap_get_sta(ap, entry->addr);
01154                 if (sta)
01155                         atomic_inc(&sta->users);
01156                 spin_unlock_bh(&ap->sta_table_lock);
01157 
01158                 if (sta) {
01159                         sprintf(name, MACSTR, MAC2STR(sta->addr));
01160                         sta->proc = create_proc_read_entry(
01161                                 name, 0, ap->proc,
01162                                 prism2_sta_proc_read, sta);
01163 
01164                         atomic_dec(&sta->users);
01165                 }
01166 
01167                 prev = entry;
01168                 entry = entry->next;
01169                 kfree(prev);
01170         }
01171 
01172 #ifndef NEW_MODULE_CODE
01173         MOD_DEC_USE_COUNT;
01174 #endif
01175 }
01176 
01177 
01178 static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr)
01179 {
01180         struct sta_info *sta;
01181 
01182         sta = (struct sta_info *)
01183                 kmalloc(sizeof(struct sta_info), GFP_ATOMIC);
01184         if (sta == NULL) {
01185                 PDEBUG(DEBUG_AP, "AP: kmalloc failed\n");
01186                 return NULL;
01187         }
01188 
01189         /* initialize STA info data */
01190         memset(sta, 0, sizeof(struct sta_info));
01191         sta->local = ap->local;
01192         skb_queue_head_init(&sta->tx_buf);
01193         memcpy(sta->addr, addr, ETH_ALEN);
01194 
01195         atomic_inc(&sta->users);
01196         spin_lock_bh(&ap->sta_table_lock);
01197         list_add(&sta->list, &ap->sta_list);
01198         ap->num_sta++;
01199         ap_sta_hash_add(ap, sta);
01200         spin_unlock_bh(&ap->sta_table_lock);
01201 
01202         if (ap->proc) {
01203                 struct add_sta_proc_data *entry;
01204                 /* schedule a non-interrupt context process to add a procfs
01205                  * entry for the STA since procfs code use GFP_KERNEL */
01206                 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
01207                 if (entry) {
01208                         memcpy(entry->addr, sta->addr, ETH_ALEN);
01209                         entry->next = ap->add_sta_proc_entries;
01210                         ap->add_sta_proc_entries = entry;
01211                         PRISM2_SCHEDULE_TASK(&ap->add_sta_proc_queue);
01212                 } else
01213                         printk(KERN_DEBUG "Failed to add STA proc data\n");
01214         }
01215 
01216 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
01217         init_timer(&sta->timer);
01218         sta->timer.expires = jiffies + ap->max_inactivity;
01219         sta->timer.data = (unsigned long) sta;
01220         sta->timer.function = ap_handle_timer;
01221         if (!ap->local->hostapd)
01222                 add_timer(&sta->timer);
01223 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
01224 
01225         return sta;
01226 }
01227 
01228 
01229 static int ap_tx_rate_ok(int rateidx, struct sta_info *sta,
01230                          local_info_t *local)
01231 {
01232         if (rateidx > sta->tx_max_rate ||
01233             !(sta->tx_supp_rates & (1 << rateidx)))
01234                 return 0;
01235 
01236         if (local->tx_rate_control != 0 &&
01237             !(local->tx_rate_control & (1 << rateidx)))
01238                 return 0;
01239 
01240         return 1;
01241 }
01242 
01243 
01244 static void prism2_check_tx_rates(struct sta_info *sta)
01245 {
01246         int i;
01247 
01248         sta->tx_supp_rates = 0;
01249         for (i = 0; i < sizeof(sta->supported_rates); i++) {
01250                 if ((sta->supported_rates[i] & 0x7f) == 2)
01251                         sta->tx_supp_rates |= WLAN_RATE_1M;
01252                 if ((sta->supported_rates[i] & 0x7f) == 4)
01253                         sta->tx_supp_rates |= WLAN_RATE_2M;
01254                 if ((sta->supported_rates[i] & 0x7f) == 11)
01255                         sta->tx_supp_rates |= WLAN_RATE_5M5;
01256                 if ((sta->supported_rates[i] & 0x7f) == 22)
01257                         sta->tx_supp_rates |= WLAN_RATE_11M;
01258         }
01259         sta->tx_max_rate = sta->tx_rate = sta->tx_rate_idx = 0;
01260         if (sta->tx_supp_rates & WLAN_RATE_1M) {
01261                 sta->tx_max_rate = 0;
01262                 if (ap_tx_rate_ok(0, sta, sta->local)) {
01263                         sta->tx_rate = 10;
01264                         sta->tx_rate_idx = 0;
01265                 }
01266         }
01267         if (sta->tx_supp_rates & WLAN_RATE_2M) {
01268                 sta->tx_max_rate = 1;
01269                 if (ap_tx_rate_ok(1, sta, sta->local)) {
01270                         sta->tx_rate = 20;
01271                         sta->tx_rate_idx = 1;
01272                 }
01273         }
01274         if (sta->tx_supp_rates & WLAN_RATE_5M5) {
01275                 sta->tx_max_rate = 2;
01276                 if (ap_tx_rate_ok(2, sta, sta->local)) {
01277                         sta->tx_rate = 55;
01278                         sta->tx_rate_idx = 2;
01279                 }
01280         }
01281         if (sta->tx_supp_rates & WLAN_RATE_11M) {
01282                 sta->tx_max_rate = 3;
01283                 if (ap_tx_rate_ok(3, sta, sta->local)) {
01284                         sta->tx_rate = 110;
01285                         sta->tx_rate_idx = 3;
01286                 }
01287         }
01288 }
01289 
01290 
01291 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
01292 
01293 static void ap_crypt_init(struct ap_data *ap)
01294 {
01295         ap->crypt = hostap_get_crypto_ops("WEP");
01296 
01297         if (ap->crypt) {
01298                 if (ap->crypt->init) {
01299                         ap->crypt_priv = ap->crypt->init();
01300                         if (ap->crypt_priv == NULL)
01301                                 ap->crypt = NULL;
01302                         else {
01303                                 u8 key[WEP_KEY_LEN];
01304                                 get_random_bytes(key, WEP_KEY_LEN);
01305                                 ap->crypt->set_key(0, key, WEP_KEY_LEN,
01306                                                    ap->crypt_priv);
01307                         }
01308                 }
01309         }
01310 
01311         if (ap->crypt == NULL) {
01312                 printk(KERN_WARNING "AP could not initialize WEP: load module "
01313                        "hostap_crypt_wep.o\n");
01314         }
01315 }
01316 
01317 
01318 /* Generate challenge data for shared key authentication. IEEE 802.11 specifies
01319  * that WEP algorithm is used for generating challange. This should be unique,
01320  * but otherwise there is not really need for randomness etc. Initialize WEP
01321  * with pseudo random key and then use increasing IV to get unique challenge
01322  * streams.
01323  *
01324  * Called only as a scheduled task for pending AP frames.
01325  */
01326 static char * ap_auth_make_challenge(struct ap_data *ap)
01327 {
01328         char *tmpbuf;
01329         int olen;
01330 
01331         if (ap->crypt == NULL) {
01332                 ap_crypt_init(ap);
01333                 if (ap->crypt == NULL)
01334                         return NULL;
01335         }
01336 
01337         tmpbuf = (char *) kmalloc(WLAN_AUTH_CHALLENGE_LEN +
01338                                   ap->crypt->extra_prefix_len +
01339                                   ap->crypt->extra_postfix_len,
01340                                   GFP_ATOMIC);
01341         if (tmpbuf == NULL) {
01342                 PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n");
01343                 return NULL;
01344         }
01345         memset(tmpbuf, 0, WLAN_AUTH_CHALLENGE_LEN +
01346                ap->crypt->extra_prefix_len + ap->crypt->extra_postfix_len);
01347         olen = ap->crypt->encrypt(tmpbuf, WLAN_AUTH_CHALLENGE_LEN,
01348                                   ap->crypt_priv);
01349         if (olen < 0) {
01350                 kfree(tmpbuf);
01351                 return NULL;
01352         }
01353         memmove(tmpbuf, tmpbuf + 4, WLAN_AUTH_CHALLENGE_LEN);
01354         return tmpbuf;
01355 }
01356 
01357 
01358 /* Called only as a scheduled task for pending AP frames. */
01359 static void handle_authen(local_info_t *local, struct sk_buff *skb,
01360                           struct hostap_80211_rx_status *rx_stats)
01361 {
01362         struct net_device *dev = local->dev;
01363         struct hostap_ieee80211_hdr *hdr =
01364                 (struct hostap_ieee80211_hdr *) skb->data;
01365         struct ap_data *ap = local->ap;
01366         char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
01367         int len, olen;
01368         u16 auth_alg, auth_transaction, status_code, *pos;
01369         u16 resp = WLAN_STATUS_SUCCESS, fc;
01370         struct sta_info *sta = NULL;
01371         struct prism2_crypt_data *crypt;
01372         char *txt = "";
01373 
01374         len = skb->len - IEEE80211_MGMT_HDR_LEN;
01375 
01376         fc = le16_to_cpu(hdr->frame_control);
01377 
01378         if (len < 6) {
01379                 PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
01380                        "(len=%d) from " MACSTR "\n", dev->name, len,
01381                        MAC2STR(hdr->addr2));
01382                 return;
01383         }
01384 
01385         spin_lock_bh(&local->ap->sta_table_lock);
01386         sta = ap_get_sta(local->ap, hdr->addr2);
01387         if (sta)
01388                 atomic_inc(&sta->users);
01389         spin_unlock_bh(&local->ap->sta_table_lock);
01390 
01391         if (sta && sta->crypt)
01392                 crypt = sta->crypt;
01393         else
01394                 crypt = local->crypt;
01395 
01396         if (crypt && local->host_decrypt && (fc & WLAN_FC_ISWEP)) {
01397                 atomic_inc(&crypt->refcnt);
01398                 olen = crypt->ops->decrypt(
01399                         (u8 *) (skb->data + IEEE80211_MGMT_HDR_LEN), len,
01400                         crypt->priv);
01401                 atomic_dec(&crypt->refcnt);
01402                 if (olen < 0) {
01403                         if (sta)
01404                                 atomic_dec(&sta->users);
01405                         PDEBUG(DEBUG_AP, "%s: handle_authen: auth frame from "
01406                                "STA " MACSTR " could not be decrypted\n",
01407                                dev->name, MAC2STR(hdr->addr2));
01408                         return;
01409                 }
01410                 if (olen < 6) {
01411                         PDEBUG(DEBUG_AP, "%s: handle_authen - too short "
01412                                "payload (len=%d, decrypted len=%d) from "
01413                                MACSTR "\n",
01414                                dev->name, len, olen, MAC2STR(hdr->addr2));
01415                         return;
01416                 }
01417                 len = olen;
01418         }
01419 
01420         pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
01421         auth_alg = __le16_to_cpu(*pos);
01422         pos++;
01423         auth_transaction = __le16_to_cpu(*pos);
01424         pos++;
01425         status_code = __le16_to_cpu(*pos);
01426         pos++;
01427 
01428         if (ap_control_mac_deny(&ap->mac_restrictions, hdr->addr2)) {
01429                 txt = "authentication denied";
01430                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01431                 goto fail;
01432         }
01433 
01434         if (((local->auth_algs & PRISM2_AUTH_OPEN) &&
01435              auth_alg == WLAN_AUTH_OPEN) ||
01436             ((local->auth_algs & PRISM2_AUTH_SHARED_KEY) &&
01437              crypt && auth_alg == WLAN_AUTH_SHARED_KEY)) {
01438         } else {
01439                 txt = "unsupported algorithm";
01440                 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
01441                 goto fail;
01442         }
01443 
01444         if (len >= 8) {
01445                 u8 *u = (u8 *) pos;
01446                 if (*u == WLAN_EID_CHALLENGE) {
01447                         if (*(u + 1) != WLAN_AUTH_CHALLENGE_LEN) {
01448                                 txt = "invalid challenge len";
01449                                 resp = WLAN_STATUS_CHALLENGE_FAIL;
01450                                 goto fail;
01451                         }
01452                         if (len - 8 < WLAN_AUTH_CHALLENGE_LEN) {
01453                                 txt = "challenge underflow";
01454                                 resp = WLAN_STATUS_CHALLENGE_FAIL;
01455                                 goto fail;
01456                         }
01457                         challenge = (char *) (u + 2);
01458                 }
01459         }
01460 
01461         if (sta && sta->ap) {
01462                 if (time_after(jiffies, sta->u.ap.last_beacon +
01463                                (10 * sta->listen_interval * HZ) / 1024)) {
01464                         PDEBUG(DEBUG_AP, "%s: no beacons received for a while,"
01465                                " assuming AP " MACSTR " is now STA\n",
01466                                dev->name, MAC2STR(sta->addr));
01467                         sta->ap = 0;
01468                         sta->flags = 0;
01469                         sta->u.sta.challenge = NULL;
01470                 } else {
01471                         txt = "AP trying to authenticate?";
01472                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01473                         goto fail;
01474                 }
01475         }
01476 
01477         if ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) ||
01478             (auth_alg == WLAN_AUTH_SHARED_KEY &&
01479              (auth_transaction == 1 ||
01480               (auth_transaction == 3 && sta != NULL &&
01481                sta->u.sta.challenge != NULL)))) {
01482         } else {
01483                 txt = "unknown authentication transaction number";
01484                 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
01485                 goto fail;
01486         }
01487 
01488         if (sta == NULL) {
01489                 txt = "new STA";
01490 
01491                 if (local->ap->num_sta >= MAX_STA_COUNT) {
01492                         /* FIX: might try to remove some old STAs first? */
01493                         txt = "no more room for new STAs";
01494                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01495                         goto fail;
01496                 }
01497 
01498                 sta = ap_add_sta(local->ap, hdr->addr2);
01499                 if (sta == NULL) {
01500                         txt = "ap_add_sta failed";
01501                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01502                         goto fail;
01503                 }
01504         }
01505 
01506         hostap_ap_update_sq(sta, rx_stats);
01507 
01508         switch (auth_alg) {
01509         case WLAN_AUTH_OPEN:
01510                 txt = "authOK";
01511                 /* IEEE 802.11 standard is not completely clear about
01512                  * whether STA is considered authenticated after
01513                  * authentication OK frame has been send or after it
01514                  * has been ACKed. In order to reduce interoperability
01515                  * issues, mark the STA authenticated before ACK. */
01516                 sta->flags |= WLAN_STA_AUTH;
01517                 break;
01518 
01519         case WLAN_AUTH_SHARED_KEY:
01520                 if (auth_transaction == 1) {
01521                         if (sta->u.sta.challenge == NULL) {
01522                                 sta->u.sta.challenge =
01523                                         ap_auth_make_challenge(local->ap);
01524                                 if (sta->u.sta.challenge == NULL) {
01525                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01526                                         goto fail;
01527                                 }
01528                         }
01529                 } else {
01530                         if (sta->u.sta.challenge == NULL ||
01531                             challenge == NULL ||
01532                             memcmp(sta->u.sta.challenge, challenge,
01533                                    WLAN_AUTH_CHALLENGE_LEN) != 0 ||
01534                             !(fc & WLAN_FC_ISWEP)) {
01535                                 txt = "challenge response incorrect";
01536                                 resp = WLAN_STATUS_CHALLENGE_FAIL;
01537                                 goto fail;
01538                         }
01539 
01540                         txt = "challenge OK - authOK";
01541                         /* IEEE 802.11 standard is not completely clear about
01542                          * whether STA is considered authenticated after
01543                          * authentication OK frame has been send or after it
01544                          * has been ACKed. In order to reduce interoperability
01545                          * issues, mark the STA authenticated before ACK. */
01546                         sta->flags |= WLAN_STA_AUTH;
01547                         kfree(sta->u.sta.challenge);
01548                         sta->u.sta.challenge = NULL;
01549                 }
01550                 break;
01551         }
01552 
01553  fail:
01554         pos = (u16 *) body;
01555         *pos = cpu_to_le16(auth_alg);
01556         pos++;
01557         *pos = cpu_to_le16(auth_transaction + 1);
01558         pos++;
01559         *pos = cpu_to_le16(resp); /* status_code */
01560         pos++;
01561         olen = 6;
01562 
01563         if (resp == WLAN_STATUS_SUCCESS && sta != NULL &&
01564             sta->u.sta.challenge != NULL &&
01565             auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 1) {
01566                 u8 *tmp = (u8 *) pos;
01567                 *tmp++ = WLAN_EID_CHALLENGE;
01568                 *tmp++ = WLAN_AUTH_CHALLENGE_LEN;
01569                 pos++;
01570                 memcpy(pos, sta->u.sta.challenge, WLAN_AUTH_CHALLENGE_LEN);
01571                 olen += 2 + WLAN_AUTH_CHALLENGE_LEN;
01572         }
01573 
01574         prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_AUTH,
01575                          body, olen, 1, hdr->addr2, ap->tx_callback_auth);
01576 
01577         if (sta) {
01578                 sta->last_rx = jiffies;
01579                 atomic_dec(&sta->users);
01580         }
01581 
01582 #if 0
01583         PDEBUG(DEBUG_AP, "%s: " MACSTR " auth (alg=%d trans#=%d stat=%d len=%d"
01584                " fc=%04x) ==> %d (%s)\n", dev->name, MAC2STR(hdr->addr2),
01585                auth_alg, auth_transaction, status_code, len, fc, resp, txt);
01586 #endif
01587 }
01588 
01589 
01590 /* Called only as a scheduled task for pending AP frames. */
01591 static void handle_assoc(local_info_t *local, struct sk_buff *skb,
01592                          struct hostap_80211_rx_status *rx_stats, int reassoc)
01593 {
01594         struct net_device *dev = local->dev;
01595         struct hostap_ieee80211_hdr *hdr =
01596                 (struct hostap_ieee80211_hdr *) skb->data;
01597         char body[12], *p, *lpos;
01598         int len, left;
01599         u16 *pos;
01600         u16 resp = WLAN_STATUS_SUCCESS;
01601         struct sta_info *sta = NULL;
01602         int send_deauth = 0;
01603         char *txt = "";
01604         u8 prev_ap[ETH_ALEN];
01605 
01606         left = len = skb->len - IEEE80211_MGMT_HDR_LEN;
01607 
01608         if (len < (reassoc ? 10 : 4)) {
01609                 PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload "
01610                        "(len=%d, reassoc=%d) from " MACSTR "\n",
01611                        dev->name, len, reassoc, MAC2STR(hdr->addr2));
01612                 return;
01613         }
01614 
01615         spin_lock_bh(&local->ap->sta_table_lock);
01616         sta = ap_get_sta(local->ap, hdr->addr2);
01617         if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
01618                 spin_unlock_bh(&local->ap->sta_table_lock);
01619                 txt = "trying to associate before authentication";
01620                 send_deauth = 1;
01621                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01622                 sta = NULL; /* do not decrement sta->users */
01623                 goto fail;
01624         }
01625         atomic_inc(&sta->users);
01626         spin_unlock_bh(&local->ap->sta_table_lock);
01627 
01628         hostap_ap_update_sq(sta, rx_stats);
01629 
01630         pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
01631         sta->capability = __le16_to_cpu(*pos);
01632         pos++; left -= 2;
01633         sta->listen_interval = __le16_to_cpu(*pos);
01634         pos++; left -= 2;
01635 
01636         if (reassoc) {
01637                 memcpy(prev_ap, pos, ETH_ALEN);
01638                 pos++; pos++; pos++; left -= 6;
01639         } else
01640                 memset(prev_ap, 0, ETH_ALEN);
01641 
01642         if (left >= 2) {
01643                 unsigned int ileft;
01644                 unsigned char *u = (unsigned char *) pos;
01645 
01646                 if (*u == WLAN_EID_SSID) {
01647                         u++; left--;
01648                         ileft = *u;
01649                         u++; left--;
01650 
01651                         if (ileft > left || ileft > MAX_SSID_LEN) {
01652                                 txt = "SSID overflow";
01653                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01654                                 goto fail;
01655                         }
01656 
01657                         if (ileft != strlen(local->essid) ||
01658                             memcmp(local->essid, u, ileft) != 0) {
01659                                 txt = "not our SSID";
01660                                 resp = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
01661                                 goto fail;
01662                         }
01663 
01664                         u += ileft;
01665                         left -= ileft;
01666                 }
01667 
01668                 if (left >= 2 && *u == WLAN_EID_SUPP_RATES) {
01669                         u++; left--;
01670                         ileft = *u;
01671                         u++; left--;
01672                         
01673                         if (ileft > left || ileft == 0 ||
01674                             ileft > WLAN_SUPP_RATES_MAX) {
01675                                 txt = "SUPP_RATES len error";
01676                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01677                                 goto fail;
01678                         }
01679 
01680                         memset(sta->supported_rates, 0,
01681                                sizeof(sta->supported_rates));
01682                         memcpy(sta->supported_rates, u, ileft);
01683                         prism2_check_tx_rates(sta);
01684 
01685                         u += ileft;
01686                         left -= ileft;
01687                 }
01688 
01689                 if (left > 0) {
01690                         PDEBUG(DEBUG_AP, "%s: assoc from " MACSTR " with extra"
01691                                " data (%d bytes) [",
01692                                dev->name, MAC2STR(hdr->addr2), left);
01693                         while (left > 0) {
01694                                 PDEBUG2(DEBUG_AP, "<%02x>", *u);
01695                                 u++; left--;
01696                         }
01697                         PDEBUG2(DEBUG_AP, "]\n");
01698                 }
01699         } else {
01700                 txt = "frame underflow";
01701                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
01702                 goto fail;
01703         }
01704 
01705         /* get a unique AID */
01706         if (sta->aid > 0)
01707                 txt = "OK, old AID";
01708         else {
01709                 spin_lock_bh(&local->ap->sta_table_lock);
01710                 for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
01711                         if (local->ap->sta_aid[sta->aid - 1] == NULL)
01712                                 break;
01713                 if (sta->aid > MAX_AID_TABLE_SIZE) {
01714                         sta->aid = 0;
01715                         spin_unlock_bh(&local->ap->sta_table_lock);
01716                         resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
01717                         txt = "no room for more AIDs";
01718                 } else {
01719                         local->ap->sta_aid[sta->aid - 1] = sta;
01720                         spin_unlock_bh(&local->ap->sta_table_lock);
01721                         txt = "OK, new AID";
01722                 }
01723         }
01724 
01725  fail:
01726         pos = (u16 *) body;
01727 
01728         if (send_deauth) {
01729                 *pos = __constant_cpu_to_le16(
01730                         WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
01731                 pos++;
01732         } else {
01733                 /* FIX: CF-Pollable and CF-PollReq should be set to match the
01734                  * values in beacons/probe responses */
01735                 /* FIX: how about privacy and WEP? */
01736                 /* capability */
01737                 *pos = __constant_cpu_to_le16(WLAN_CAPABILITY_ESS);
01738                 pos++;
01739 
01740                 /* status_code */
01741                 *pos = __cpu_to_le16(resp);
01742                 pos++;
01743 
01744                 *pos = __cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) |
01745                                      BIT(14) | BIT(15)); /* AID */
01746                 pos++;
01747 
01748                 /* Supported rates (Information element) */
01749                 p = (char *) pos;
01750                 *p++ = WLAN_EID_SUPP_RATES;
01751                 lpos = p;
01752                 *p++ = 0; /* len */
01753                 if (local->tx_rate_control & WLAN_RATE_1M) {
01754                         *p++ = local->basic_rates & WLAN_RATE_1M ? 0x82 : 0x02;
01755                         (*lpos)++;
01756                 }
01757                 if (local->tx_rate_control & WLAN_RATE_2M) {
01758                         *p++ = local->basic_rates & WLAN_RATE_2M ? 0x84 : 0x04;
01759                         (*lpos)++;
01760                 }
01761                 if (local->tx_rate_control & WLAN_RATE_5M5) {
01762                         *p++ = local->basic_rates & WLAN_RATE_5M5 ?
01763                                 0x8b : 0x0b;
01764                         (*lpos)++;
01765                 }
01766                 if (local->tx_rate_control & WLAN_RATE_11M) {
01767                         *p++ = local->basic_rates & WLAN_RATE_11M ?
01768                                 0x96 : 0x16;
01769                         (*lpos)++;
01770                 }
01771                 pos = (u16 *) p;
01772         }
01773 
01774         prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT,
01775                          (send_deauth ? WLAN_FC_STYPE_DEAUTH :
01776                           (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
01777                            WLAN_FC_STYPE_ASSOC_RESP)),
01778                          body, (u8 *) pos - (u8 *) body, 1,
01779                          hdr->addr2,
01780                          send_deauth ? 0 : local->ap->tx_callback_assoc);
01781 
01782         if (sta) {
01783                 if (resp == WLAN_STATUS_SUCCESS) {
01784                         sta->last_rx = jiffies;
01785                         /* STA will be marked associated from TX callback, if
01786                          * AssocResp is ACKed */
01787                 }
01788                 atomic_dec(&sta->users);
01789         }
01790 
01791 #if 0
01792         PDEBUG(DEBUG_AP, "%s: " MACSTR " %sassoc (len=%d prev_ap=" MACSTR
01793                ") => %d(%d) (%s)\n",
01794                dev->name, MAC2STR(hdr->addr2), reassoc ? "re" : "", len,
01795                MAC2STR(prev_ap), resp, send_deauth, txt);
01796 #endif
01797 }
01798 
01799 
01800 /* Called only as a scheduled task for pending AP frames. */
01801 static void handle_deauth(local_info_t *local, struct sk_buff *skb,
01802                           struct hostap_80211_rx_status *rx_stats)
01803 {
01804         struct net_device *dev = local->dev;
01805         struct hostap_ieee80211_hdr *hdr =
01806                 (struct hostap_ieee80211_hdr *) skb->data;
01807         char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
01808         int len;
01809         u16 reason_code, *pos;
01810         struct sta_info *sta = NULL;
01811 
01812         len = skb->len - IEEE80211_MGMT_HDR_LEN;
01813 
01814         if (len < 2) {
01815                 printk("handle_deauth - too short payload (len=%d)\n", len);
01816                 return;
01817         }
01818 
01819         pos = (u16 *) body;
01820         reason_code = __le16_to_cpu(*pos);
01821 
01822         PDEBUG(DEBUG_AP, "%s: deauthentication: " MACSTR " len=%d, "
01823                "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
01824                reason_code);
01825 
01826         spin_lock_bh(&local->ap->sta_table_lock);
01827         sta = ap_get_sta(local->ap, hdr->addr2);
01828         if (sta != NULL) {
01829                 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
01830                         hostap_event_expired_sta(local->dev, sta);
01831                 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
01832                 hostap_ap_update_sq(sta, rx_stats);
01833         }
01834         spin_unlock_bh(&local->ap->sta_table_lock);
01835         if (sta == NULL) {
01836                 printk("%s: deauthentication from " MACSTR ", "
01837                "reason_code=%d, but STA not authenticated\n", dev->name,
01838                        MAC2STR(hdr->addr2), reason_code);
01839         }
01840 }
01841 
01842 
01843 /* Called only as a scheduled task for pending AP frames. */
01844 static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
01845                             struct hostap_80211_rx_status *rx_stats)
01846 {
01847         struct net_device *dev = local->dev;
01848         struct hostap_ieee80211_hdr *hdr =
01849                 (struct hostap_ieee80211_hdr *) skb->data;
01850         char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
01851         int len;
01852         u16 reason_code, *pos;
01853         struct sta_info *sta = NULL;
01854 
01855         len = skb->len - IEEE80211_MGMT_HDR_LEN;
01856 
01857         if (len < 2) {
01858                 printk("handle_disassoc - too short payload (len=%d)\n", len);
01859                 return;
01860         }
01861 
01862         pos = (u16 *) body;
01863         reason_code = __le16_to_cpu(*pos);
01864 
01865         PDEBUG(DEBUG_AP, "%s: disassociation: " MACSTR " len=%d, "
01866                "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
01867                reason_code);
01868 
01869         spin_lock_bh(&local->ap->sta_table_lock);
01870         sta = ap_get_sta(local->ap, hdr->addr2);
01871         if (sta != NULL) {
01872                 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
01873                         hostap_event_expired_sta(local->dev, sta);
01874                 sta->flags &= ~WLAN_STA_ASSOC;
01875                 hostap_ap_update_sq(sta, rx_stats);
01876         }
01877         spin_unlock_bh(&local->ap->sta_table_lock);
01878         if (sta == NULL) {
01879                 printk("%s: disassociation from " MACSTR ", "
01880                        "reason_code=%d, but STA not authenticated\n",
01881                        dev->name, MAC2STR(hdr->addr2), reason_code);
01882         }
01883 }
01884 
01885 
01886 /* Called only as a scheduled task for pending AP frames. */
01887 static void ap_handle_data_nullfunc(local_info_t *local,
01888                                     struct hostap_ieee80211_hdr *hdr)
01889 {
01890         struct net_device *dev = local->dev;
01891 
01892         /* some STA f/w's seem to require control::ACK frame for
01893          * data::nullfunc, but at least Prism2 station f/w version 0.8.0 does
01894          * not send this..
01895          * send control::ACK for the data::nullfunc */
01896 
01897         printk(KERN_DEBUG "Sending control::ACK for data::nullfunc\n");
01898         prism2_send_mgmt(dev, WLAN_FC_TYPE_CTRL, WLAN_FC_STYPE_ACK,
01899                          NULL, 0, 0, hdr->addr2, 0);
01900 }
01901 
01902 
01903 /* Called only as a scheduled task for pending AP frames. */
01904 static void ap_handle_dropped_data(local_info_t *local,
01905                                    struct hostap_ieee80211_hdr *hdr)
01906 {
01907         struct net_device *dev = local->dev;
01908         struct sta_info *sta;
01909         u16 reason;
01910 
01911         spin_lock_bh(&local->ap->sta_table_lock);
01912         sta = ap_get_sta(local->ap, hdr->addr2);
01913         if (sta)
01914                 atomic_inc(&sta->users);
01915         spin_unlock_bh(&local->ap->sta_table_lock);
01916 
01917         if (sta != NULL && (sta->flags & WLAN_STA_ASSOC)) {
01918                 PDEBUG(DEBUG_AP, "ap_handle_dropped_data: STA is now okay?\n");
01919                 atomic_dec(&sta->users);
01920                 return;
01921         }
01922 
01923         reason = __constant_cpu_to_le16(
01924                 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
01925         prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT,
01926                          ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ?
01927                           WLAN_FC_STYPE_DEAUTH : WLAN_FC_STYPE_DISASSOC),
01928                          (char *) &reason, sizeof(reason), 1,
01929                          hdr->addr2, 0);
01930 
01931         if (sta)
01932                 atomic_dec(&sta->users);
01933 }
01934 
01935 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
01936 
01937 
01938 /* Called only as a scheduled task for pending AP frames. */
01939 static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
01940                                  struct sk_buff *skb)
01941 {
01942         if (!(sta->flags & WLAN_STA_PS)) {
01943                 /* Station has moved to non-PS mode, so send all buffered
01944                  * frames using normal device queue. */
01945                 dev_queue_xmit(skb);
01946                 return;
01947         }
01948 
01949         /* add a flag for hostap_handle_sta_tx() to know that this skb should
01950          * be passed through even though STA is using PS */
01951         memcpy(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN);
01952         skb->cb[AP_SKB_CB_MAGIC_LEN] = AP_SKB_CB_BUFFERED_FRAME;
01953         if (!skb_queue_empty(&sta->tx_buf)) {
01954                 /* indicate to STA that more frames follow */
01955                 skb->cb[AP_SKB_CB_MAGIC_LEN] |= AP_SKB_CB_ADD_MOREDATA;
01956         }
01957         if (skb->dev->hard_start_xmit(skb, skb->dev)) {
01958                 PDEBUG(DEBUG_AP, "%s: TX failed for buffered frame (PS Poll)"
01959                        "\n", skb->dev->name);
01960                 dev_kfree_skb(skb);
01961         }
01962 }
01963 
01964 
01965 /* Called only as a scheduled task for pending AP frames. */
01966 static void handle_pspoll(local_info_t *local,
01967                           struct hostap_ieee80211_hdr *hdr,
01968                           struct hostap_80211_rx_status *rx_stats)
01969 {
01970         struct net_device *dev = local->dev;
01971         struct sta_info *sta;
01972         u16 aid;
01973         struct sk_buff *skb;
01974 
01975         PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR
01976                " PWRMGT=%d\n",
01977                MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
01978                !!(le16_to_cpu(hdr->frame_control) & WLAN_FC_PWRMGT));
01979 
01980         if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
01981                 PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR
01982                        " not own MAC\n", MAC2STR(hdr->addr1));
01983                 return;
01984         }
01985 
01986         aid = __le16_to_cpu(hdr->duration_id);
01987         if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) {
01988                 PDEBUG(DEBUG_PS, "   PSPOLL and AID[15:14] not set\n");
01989                 return;
01990         }
01991         aid &= ~BIT(15) & ~BIT(14);
01992         if (aid == 0 || aid > MAX_AID_TABLE_SIZE) {
01993                 PDEBUG(DEBUG_PS, "   invalid aid=%d\n", aid);
01994                 return;
01995         }
01996         PDEBUG(DEBUG_PS2, "   aid=%d\n", aid);
01997 
01998         spin_lock_bh(&local->ap->sta_table_lock);
01999         sta = ap_get_sta(local->ap, hdr->addr2);
02000         if (sta)
02001                 atomic_inc(&sta->users);
02002         spin_unlock_bh(&local->ap->sta_table_lock);
02003 
02004         if (sta == NULL) {
02005                 PDEBUG(DEBUG_PS, "   STA not found\n");
02006                 return;
02007         }
02008         hostap_ap_update_sq(sta, rx_stats);
02009         if (sta->aid != aid) {
02010                 PDEBUG(DEBUG_PS, "   received aid=%i does not match with "
02011                        "assoc.aid=%d\n", aid, sta->aid);
02012                 return;
02013         }
02014 
02015         /* FIX: todo:
02016          * - add timeout for buffering (clear aid in TIM vector if buffer timed
02017          *   out (expiry time must be longer than ListenInterval for
02018          *   the corresponding STA; "8802-11: 11.2.1.9 AP aging function"
02019          * - what to do, if buffered, pspolled, and sent frame is not ACKed by
02020          *   sta; store buffer for later use and leave TIM aid bit set? use
02021          *   TX event to check whether frame was ACKed?
02022          */
02023 
02024         while ((skb = skb_dequeue(&sta->tx_buf)) != NULL) {
02025                 /* send buffered frame .. */
02026                 PDEBUG(DEBUG_PS2, "Sending buffered frame to STA after PS POLL"
02027                        " (buffer_count=%d)\n", skb_queue_len(&sta->tx_buf));
02028 
02029                 pspoll_send_buffered(local, sta, skb);
02030 
02031                 if (sta->flags & WLAN_STA_PS) {
02032                         /* send only one buffered packet per PS Poll */
02033                         /* FIX: should ignore further PS Polls until the
02034                          * buffered packet that was just sent is acknowledged
02035                          * (Tx or TxExc event) */
02036                         break;
02037                 }
02038         }
02039 
02040         if (skb_queue_empty(&sta->tx_buf)) {
02041                 /* try to clear aid from TIM */
02042                 if (!(sta->flags & WLAN_STA_TIM))
02043                         PDEBUG(DEBUG_PS2,  "Re-unsetting TIM for aid %d\n",
02044                                aid);
02045                 hostap_set_tim(local, aid, 0);
02046                 sta->flags &= ~WLAN_STA_TIM;
02047         }
02048 
02049         atomic_dec(&sta->users);
02050 }
02051 
02052 
02053 void hostap_ap_update_sq(struct sta_info *sta,
02054                          struct hostap_80211_rx_status *rx_stats)
02055 {
02056         sta->last_rx_silence = rx_stats->noise;
02057         sta->last_rx_signal = rx_stats->signal;
02058         sta->last_rx_rate = rx_stats->rate;
02059         sta->last_rx_updated = 7;
02060         if (rx_stats->rate == 10)
02061                 sta->rx_count[0]++;
02062         else if (rx_stats->rate == 20)
02063                 sta->rx_count[1]++;
02064         else if (rx_stats->rate == 55)
02065                 sta->rx_count[2]++;
02066         else if (rx_stats->rate == 110)
02067                 sta->rx_count[3]++;
02068 }
02069 
02070 
02071 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
02072 
02073 static void handle_wds_oper_queue(void *data)
02074 {
02075         local_info_t *local = data;
02076         struct wds_oper_data *entry, *prev;
02077 
02078         spin_lock_bh(&local->lock);
02079         entry = local->ap->wds_oper_entries;
02080         local->ap->wds_oper_entries = NULL;
02081         spin_unlock_bh(&local->lock);
02082 
02083         while (entry) {
02084                 PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection "
02085                        "to AP " MACSTR "\n",
02086                        local->dev->name,
02087                        entry->type == WDS_ADD ? "adding" : "removing",
02088                        MAC2STR(entry->addr));
02089                 if (entry->type == WDS_ADD)
02090                         prism2_wds_add(local, entry->addr, 0);
02091                 else if (entry->type == WDS_DEL)
02092                         prism2_wds_del(local, entry->addr, 0, 1);
02093 
02094                 prev = entry;
02095                 entry = entry->next;
02096                 kfree(prev);
02097         }
02098 
02099 #ifndef NEW_MODULE_CODE
02100         MOD_DEC_USE_COUNT;
02101 #endif
02102 }
02103 
02104 
02105 /* Called only as a scheduled task for pending AP frames. */
02106 static void handle_beacon(local_info_t *local, struct sk_buff *skb,
02107                           struct hostap_80211_rx_status *rx_stats)
02108 {
02109         struct hostap_ieee80211_hdr *hdr =
02110                 (struct hostap_ieee80211_hdr *) skb->data;
02111         char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
02112         int len, left;
02113         u16 *pos, beacon_int, capability;
02114         char *ssid = NULL;
02115         unsigned char *supp_rates = NULL;
02116         int ssid_len = 0, supp_rates_len = 0;
02117         struct sta_info *sta = NULL;
02118         int new_sta = 0, channel = -1;
02119 
02120         len = skb->len - IEEE80211_MGMT_HDR_LEN;
02121 
02122         if (len < 8 + 2 + 2) {
02123                 printk(KERN_DEBUG "handle_beacon - too short payload "
02124                        "(len=%d)\n", len);
02125                 return;
02126         }
02127 
02128         pos = (u16 *) body;
02129         left = len;
02130 
02131         /* Timestamp (8 octets) */
02132         pos += 4; left -= 8;
02133         /* Beacon interval (2 octets) */
02134         beacon_int = __le16_to_cpu(*pos);
02135         pos++; left -= 2;
02136         /* Capability information (2 octets) */
02137         capability = __le16_to_cpu(*pos);
02138         pos++; left -= 2;
02139 
02140         if (local->ap->ap_policy != AP_OTHER_AP_EVEN_IBSS &&
02141             capability & WLAN_CAPABILITY_IBSS)
02142                 return;
02143 
02144         if (left >= 2) {
02145                 unsigned int ileft;
02146                 unsigned char *u = (unsigned char *) pos;
02147 
02148                 if (*u == WLAN_EID_SSID) {
02149                         u++; left--;
02150                         ileft = *u;
02151                         u++; left--;
02152 
02153                         if (ileft > left || ileft > MAX_SSID_LEN) {
02154                                 PDEBUG(DEBUG_AP, "SSID: overflow\n");
02155                                 return;
02156                         }
02157 
02158                         if (local->ap->ap_policy == AP_OTHER_AP_SAME_SSID &&
02159                             (ileft != strlen(local->essid) ||
02160                              memcmp(local->essid, u, ileft) != 0)) {
02161                                 /* not our SSID */
02162                                 return;
02163                         }
02164 
02165                         ssid = u;
02166                         ssid_len = ileft;
02167 
02168                         u += ileft;
02169                         left -= ileft;
02170                 }
02171 
02172                 if (*u == WLAN_EID_SUPP_RATES) {
02173                         u++; left--;
02174                         ileft = *u;
02175                         u++; left--;
02176                         
02177                         if (ileft > left || ileft == 0 || ileft > 8) {
02178                                 PDEBUG(DEBUG_AP, " - SUPP_RATES len error\n");
02179                                 return;
02180                         }
02181 
02182                         supp_rates = u;
02183                         supp_rates_len = ileft;
02184 
02185                         u += ileft;
02186                         left -= ileft;
02187                 }
02188 
02189                 if (*u == WLAN_EID_DS_PARAMS) {
02190                         u++; left--;
02191                         ileft = *u;
02192                         u++; left--;
02193                         
02194                         if (ileft > left || ileft != 1) {
02195                                 PDEBUG(DEBUG_AP, " - DS_PARAMS len error\n");
02196                                 return;
02197                         }
02198 
02199                         channel = *u;
02200 
02201                         u += ileft;
02202                         left -= ileft;
02203                 }
02204         }
02205 
02206         spin_lock_bh(&local->ap->sta_table_lock);
02207         sta = ap_get_sta(local->ap, hdr->addr2);
02208         if (sta != NULL)
02209                 atomic_inc(&sta->users);
02210         spin_unlock_bh(&local->ap->sta_table_lock);
02211 
02212         if (sta == NULL) {
02213                 /* add new AP */
02214                 new_sta = 1;
02215                 sta = ap_add_sta(local->ap, hdr->addr2);
02216                 if (sta == NULL) {
02217                         printk(KERN_INFO "prism2: kmalloc failed for AP "
02218                                "data structure\n");
02219                         return;
02220                 }
02221                 hostap_event_new_sta(local->dev, sta);
02222 
02223                 /* mark APs authentication and associated for pseudo ad-hoc
02224                  * style communication */
02225                 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
02226 
02227                 if (local->ap->autom_ap_wds) {
02228                         hostap_wds_link_oper(local, sta->addr, WDS_ADD);
02229                 }
02230         }
02231 
02232         sta->ap = 1;
02233         if (ssid) {
02234                 sta->u.ap.ssid_len = ssid_len;
02235                 memcpy(sta->u.ap.ssid, ssid, ssid_len);
02236                 sta->u.ap.ssid[ssid_len] = '\0';
02237         } else {
02238                 sta->u.ap.ssid_len = 0;
02239                 sta->u.ap.ssid[0] = '\0';
02240         }
02241         sta->u.ap.channel = channel;
02242         sta->rx_packets++;
02243         sta->rx_bytes += len;
02244         sta->u.ap.last_beacon = sta->last_rx = jiffies;
02245         sta->capability = capability;
02246         sta->listen_interval = beacon_int;
02247         hostap_ap_update_sq(sta, rx_stats);
02248 
02249         atomic_dec(&sta->users);
02250 
02251         if (new_sta) {
02252                 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
02253                 memcpy(sta->supported_rates, supp_rates, supp_rates_len);
02254                 prism2_check_tx_rates(sta);
02255         }
02256 }
02257 
02258 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
02259 
02260 
02261 /* Called only as a tasklet. */
02262 static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
02263                            struct hostap_80211_rx_status *rx_stats)
02264 {
02265 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
02266         struct net_device *dev = local->dev;
02267 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
02268         u16 fc, type, stype;
02269         struct hostap_ieee80211_hdr *hdr;
02270 
02271         /* FIX: should give skb->len to handler functions and check that the
02272          * buffer is long enough */
02273         hdr = (struct hostap_ieee80211_hdr *) skb->data;
02274         fc = le16_to_cpu(hdr->frame_control);
02275         type = WLAN_FC_GET_TYPE(fc);
02276         stype = WLAN_FC_GET_STYPE(fc);
02277 
02278 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
02279         if (!local->hostapd && type == WLAN_FC_TYPE_DATA) {
02280                 PDEBUG(DEBUG_AP, "handle_ap_item - data frame\n");
02281 
02282                 if (!(fc & WLAN_FC_TODS) || (fc & WLAN_FC_FROMDS)) {
02283                         if (stype == WLAN_FC_STYPE_NULLFUNC) {
02284                                 /* no ToDS nullfunc seems to be used to check
02285                                  * AP association; so send reject message to
02286                                  * speed up re-association */
02287                                 ap_handle_dropped_data(local, hdr);
02288                                 goto done;
02289                         }
02290                         PDEBUG(DEBUG_AP, "   not ToDS frame (fc=0x%04x)\n",
02291                                fc);
02292                         goto done;
02293                 }
02294 
02295                 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
02296                         PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)="
02297                                MACSTR " not own MAC\n",
02298                                MAC2STR(hdr->addr1));
02299                         goto done;
02300                 }
02301 
02302                 if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC)
02303                         ap_handle_data_nullfunc(local, hdr);
02304                 else
02305                         ap_handle_dropped_data(local, hdr);
02306                 goto done;
02307         }
02308 
02309         if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_BEACON) {
02310                 handle_beacon(local, skb, rx_stats);
02311                 goto done;
02312         }
02313 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
02314 
02315         if (type == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL) {
02316                 handle_pspoll(local, hdr, rx_stats);
02317                 goto done;
02318         }
02319 
02320         if (local->hostapd) {
02321                 PDEBUG(DEBUG_AP, "Unknown frame in AP queue: type=0x%02x "
02322                        "subtype=0x%02x\n", type, stype);
02323                 goto done;
02324         }
02325 
02326 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
02327         if (type != WLAN_FC_TYPE_MGMT) {
02328                 PDEBUG(DEBUG_AP, "handle_ap_item - not a management frame?\n");
02329                 goto done;
02330         }
02331 
02332         if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
02333                 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MACSTR
02334                        " not own MAC\n", MAC2STR(hdr->addr1));
02335                 goto done;
02336         }
02337 
02338         if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) {
02339                 PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MACSTR
02340                        " not own MAC\n", MAC2STR(hdr->addr3));
02341                 goto done;
02342         }
02343 
02344         switch (stype) {
02345         case WLAN_FC_STYPE_ASSOC_REQ:
02346                 handle_assoc(local, skb, rx_stats, 0);
02347                 break;
02348         case WLAN_FC_STYPE_ASSOC_RESP:
02349                 PDEBUG(DEBUG_AP, "==> ASSOC RESP (ignored)\n");
02350                 break;
02351         case WLAN_FC_STYPE_REASSOC_REQ:
02352                 handle_assoc(local, skb, rx_stats, 1);
02353                 break;
02354         case WLAN_FC_STYPE_REASSOC_RESP:
02355                 PDEBUG(DEBUG_AP, "==> REASSOC RESP (ignored)\n");
02356                 break;
02357         case WLAN_FC_STYPE_ATIM:
02358                 PDEBUG(DEBUG_AP, "==> ATIM (ignored)\n");
02359                 break;
02360         case WLAN_FC_STYPE_DISASSOC:
02361                 handle_disassoc(local, skb, rx_stats);
02362                 break;
02363         case WLAN_FC_STYPE_AUTH:
02364                 handle_authen(local, skb, rx_stats);
02365                 break;
02366         case WLAN_FC_STYPE_DEAUTH:
02367                 handle_deauth(local, skb, rx_stats);
02368                 break;
02369         default:
02370                 PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n", stype);
02371                 break;
02372         }
02373 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
02374 
02375  done:
02376         dev_kfree_skb(skb);
02377 }
02378 
02379 
02380 /* Called only as a tasklet (software IRQ) */
02381 void hostap_rx(struct net_device *dev, struct sk_buff *skb,
02382                struct hostap_80211_rx_status *rx_stats)
02383 {
02384         struct hostap_interface *iface = dev->priv;
02385         local_info_t *local = iface->local;
02386         u16 fc;
02387         struct hostap_ieee80211_hdr *hdr;
02388 
02389         if (skb->len < 16)
02390                 goto drop;
02391 
02392         local->stats.rx_packets++;
02393 
02394         hdr = (struct hostap_ieee80211_hdr *) skb->data;
02395         fc = le16_to_cpu(hdr->frame_control);
02396 
02397         if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
02398             WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
02399             WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
02400                 goto drop;
02401 
02402         skb->protocol = __constant_htons(ETH_P_HOSTAP);
02403         handle_ap_item(local, skb, rx_stats);
02404         return;
02405 
02406  drop:
02407         dev_kfree_skb(skb);
02408 }
02409 
02410 
02411 /* Called only as a tasklet (software IRQ) */
02412 static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
02413 {
02414         struct sk_buff *skb;
02415         struct hostap_ieee80211_hdr *hdr;
02416         struct hostap_80211_rx_status rx_stats;
02417 
02418         if (skb_queue_empty(&sta->tx_buf))
02419                 return;
02420 
02421         skb = dev_alloc_skb(16);
02422         if (skb == NULL) {
02423                 printk(KERN_DEBUG "%s: schedule_packet_send: skb alloc "
02424                        "failed\n", local->dev->name);
02425                 return;
02426         }
02427 
02428         hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, 16);
02429 
02430         /* Generate a fake pspoll frame to start packet delivery */
02431         hdr->frame_control = __constant_cpu_to_le16(
02432                 (WLAN_FC_TYPE_CTRL << 2) | (WLAN_FC_STYPE_PSPOLL << 4));
02433         memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
02434         memcpy(hdr->addr2, sta->addr, ETH_ALEN);
02435         hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14));
02436 
02437         PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for "
02438                "STA " MACSTR "\n", local->dev->name, MAC2STR(sta->addr));
02439 
02440         skb->dev = local->dev;
02441 
02442         memset(&rx_stats, 0, sizeof(rx_stats));
02443         hostap_rx(local->dev, skb, &rx_stats);
02444 }
02445 
02446 
02447 #ifdef WIRELESS_EXT
02448 static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
02449                                   struct iw_quality qual[], int buf_size,
02450                                   int aplist)
02451 {
02452         struct ap_data *ap = local->ap;
02453         struct list_head *ptr;
02454         int count = 0;
02455 
02456         spin_lock_bh(&ap->sta_table_lock);
02457 
02458         for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
02459              ptr = ptr->next) {
02460                 struct sta_info *sta = (struct sta_info *) ptr;
02461 
02462                 if (aplist && !sta->ap)
02463                         continue;
02464                 addr[count].sa_family = ARPHRD_ETHER;
02465                 memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
02466                 if (sta->last_rx_silence == 0)
02467                         qual[count].qual = sta->last_rx_signal < 27 ?
02468                                 0 : (sta->last_rx_signal - 27) * 92 / 127;
02469                 else
02470                         qual[count].qual = sta->last_rx_signal -
02471                                 sta->last_rx_silence - 35;
02472                 qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
02473                 qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
02474                 qual[count].updated = sta->last_rx_updated;
02475 
02476                 sta->last_rx_updated = 0;
02477 
02478                 count++;
02479                 if (count >= buf_size)
02480                         break;
02481         }
02482         spin_unlock_bh(&ap->sta_table_lock);
02483 
02484         return count;
02485 }
02486 
02487 
02488 #if WIRELESS_EXT > 13
02489 /* Translate our list of Access Points & Stations to a card independant
02490  * format that the Wireless Tools will understand - Jean II */
02491 static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
02492 {
02493         struct hostap_interface *iface = dev->priv;
02494         local_info_t *local = iface->local;
02495         struct ap_data *ap = local->ap;
02496         struct list_head *ptr;
02497         struct iw_event iwe;
02498         char *current_ev = buffer;
02499         char *end_buf = buffer + IW_SCAN_MAX_DATA;
02500 #if !defined(PRISM2_NO_KERNEL_IEEE80211_MGMT) && (WIRELESS_EXT > 14)
02501         char buf[64];
02502 #endif
02503 
02504         spin_lock_bh(&ap->sta_table_lock);
02505 
02506         for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
02507              ptr = ptr->next) {
02508                 struct sta_info *sta = (struct sta_info *) ptr;
02509 
02510                 /* First entry *MUST* be the AP MAC address */
02511                 memset(&iwe, 0, sizeof(iwe));
02512                 iwe.cmd = SIOCGIWAP;
02513                 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
02514                 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
02515                 iwe.len = IW_EV_ADDR_LEN;
02516                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
02517                                                   IW_EV_ADDR_LEN);
02518 
02519                 /* Use the mode to indicate if it's a station or
02520                  * an Access Point */
02521                 memset(&iwe, 0, sizeof(iwe));
02522                 iwe.cmd = SIOCGIWMODE;
02523                 if (sta->ap)
02524                         iwe.u.mode = IW_MODE_MASTER;
02525                 else
02526                         iwe.u.mode = IW_MODE_INFRA;
02527                 iwe.len = IW_EV_UINT_LEN;
02528                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
02529                                                   IW_EV_UINT_LEN);
02530 
02531                 /* Some quality */
02532                 memset(&iwe, 0, sizeof(iwe));
02533                 iwe.cmd = IWEVQUAL;
02534                 if (sta->last_rx_silence == 0)
02535                         iwe.u.qual.qual = sta->last_rx_signal < 27 ?
02536                                 0 : (sta->last_rx_signal - 27) * 92 / 127;
02537                 else
02538                         iwe.u.qual.qual = sta->last_rx_signal -
02539                                 sta->last_rx_silence - 35;
02540                 iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
02541                 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
02542                 iwe.u.qual.updated = sta->last_rx_updated;
02543                 iwe.len = IW_EV_QUAL_LEN;
02544                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
02545                                                   IW_EV_QUAL_LEN);
02546 
02547 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
02548                 if (sta->ap) {
02549                         memset(&iwe, 0, sizeof(iwe));
02550                         iwe.cmd = SIOCGIWESSID;
02551                         iwe.u.data.length = sta->u.ap.ssid_len;
02552                         iwe.u.data.flags = 1;
02553                         current_ev = iwe_stream_add_point(current_ev, end_buf,
02554                                                           &iwe,
02555                                                           sta->u.ap.ssid);
02556 
02557                         memset(&iwe, 0, sizeof(iwe));
02558                         iwe.cmd = SIOCGIWENCODE;
02559                         if (sta->capability & WLAN_CAPABILITY_PRIVACY)
02560                                 iwe.u.data.flags =
02561                                         IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
02562                         else
02563                                 iwe.u.data.flags = IW_ENCODE_DISABLED;
02564                         current_ev = iwe_stream_add_point(current_ev, end_buf,
02565                                                           &iwe,
02566                                                           sta->u.ap.ssid
02567                                                           /* 0 byte memcpy */);
02568 
02569                         if (sta->u.ap.channel > 0 &&
02570                             sta->u.ap.channel <= FREQ_COUNT) {
02571                                 memset(&iwe, 0, sizeof(iwe));
02572                                 iwe.cmd = SIOCGIWFREQ;
02573                                 iwe.u.freq.m = freq_list[sta->u.ap.channel - 1]
02574                                         * 100000;
02575                                 iwe.u.freq.e = 1;
02576                                 current_ev = iwe_stream_add_event(
02577                                         current_ev, end_buf, &iwe,
02578                                         IW_EV_FREQ_LEN);
02579                         }
02580 
02581 #if WIRELESS_EXT > 14
02582                         memset(&iwe, 0, sizeof(iwe));
02583                         iwe.cmd = IWEVCUSTOM;
02584                         sprintf(buf, "beacon_interval=%d",
02585                                 sta->listen_interval);
02586                         iwe.u.data.length = strlen(buf);
02587                         current_ev = iwe_stream_add_point(current_ev, end_buf,
02588                                                           &iwe, buf);
02589 #endif /* WIRELESS_EXT > 14 */
02590                 }
02591 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
02592 
02593                 sta->last_rx_updated = 0;
02594 
02595                 /* To be continued, we should make good use of IWEVCUSTOM */
02596         }
02597 
02598         spin_unlock_bh(&ap->sta_table_lock);
02599 
02600         return current_ev - buffer;
02601 }
02602 #endif /* WIRELESS_EXT > 13 */
02603 #endif /* WIRELESS_EXT */
02604 
02605 
02606 static int prism2_hostapd_add_sta(struct ap_data *ap,
02607                                   struct prism2_hostapd_param *param)
02608 {
02609         struct sta_info *sta;
02610 
02611         spin_lock_bh(&ap->sta_table_lock);
02612         sta = ap_get_sta(ap, param->sta_addr);
02613         if (sta)
02614                 atomic_inc(&sta->users);
02615         spin_unlock_bh(&ap->sta_table_lock);
02616 
02617         if (sta == NULL) {
02618                 sta = ap_add_sta(ap, param->sta_addr);
02619                 if (sta == NULL)
02620                         return -1;
02621         }
02622 
02623         if (!(sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
02624                 hostap_event_new_sta(sta->local->dev, sta);
02625 
02626         sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
02627         sta->last_rx = jiffies;
02628         sta->aid = param->u.add_sta.aid;
02629         sta->capability = param->u.add_sta.capability;
02630         sta->tx_supp_rates = param->u.add_sta.tx_supp_rates;
02631         if (sta->tx_supp_rates & WLAN_RATE_1M)
02632                 sta->supported_rates[0] = 2;
02633         if (sta->tx_supp_rates & WLAN_RATE_2M)
02634                 sta->supported_rates[1] = 4;
02635         if (sta->tx_supp_rates & WLAN_RATE_5M5)
02636                 sta->supported_rates[2] = 11;
02637         if (sta->tx_supp_rates & WLAN_RATE_11M)
02638                 sta->supported_rates[3] = 22;
02639         prism2_check_tx_rates(sta);
02640         atomic_dec(&sta->users);
02641         return 0;
02642 }
02643 
02644 
02645 static int prism2_hostapd_remove_sta(struct ap_data *ap,
02646                                      struct prism2_hostapd_param *param)
02647 {
02648         struct sta_info *sta;
02649 
02650         spin_lock_bh(&ap->sta_table_lock);
02651         sta = ap_get_sta(ap, param->sta_addr);
02652         if (sta) {
02653                 ap_sta_hash_del(ap, sta);
02654                 list_del(&sta->list);
02655         }
02656         spin_unlock_bh(&ap->sta_table_lock);
02657 
02658         if (!sta)
02659                 return -ENOENT;
02660 
02661         if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
02662                 hostap_event_expired_sta(sta->local->dev, sta);
02663         ap_free_sta(ap, sta);
02664 
02665         return 0;
02666 }
02667 
02668 
02669 static int prism2_hostapd_get_info_sta(struct ap_data *ap,
02670                                        struct prism2_hostapd_param *param)
02671 {
02672         struct sta_info *sta;
02673 
02674         spin_lock_bh(&ap->sta_table_lock);
02675         sta = ap_get_sta(ap, param->sta_addr);
02676         if (sta)
02677                 atomic_inc(&sta->users);
02678         spin_unlock_bh(&ap->sta_table_lock);
02679 
02680         if (!sta)
02681                 return -ENOENT;
02682 
02683         param->u.get_info_sta.inactive_sec = (jiffies - sta->last_rx) / HZ;
02684 
02685         atomic_dec(&sta->users);
02686 
02687         return 1;
02688 }
02689 
02690 
02691 static int prism2_hostapd_set_flags_sta(struct ap_data *ap,
02692                                         struct prism2_hostapd_param *param)
02693 {
02694         struct sta_info *sta;
02695 
02696         spin_lock_bh(&ap->sta_table_lock);
02697         sta = ap_get_sta(ap, param->sta_addr);
02698         if (sta) {
02699                 sta->flags |= param->u.set_flags_sta.flags_or;
02700                 sta->flags &= param->u.set_flags_sta.flags_and;
02701         }
02702         spin_unlock_bh(&ap->sta_table_lock);
02703 
02704         if (!sta)
02705                 return -ENOENT;
02706 
02707         return 0;
02708 }
02709 
02710 
02711 static int prism2_hostapd(struct ap_data *ap,
02712                           struct prism2_hostapd_param *param)
02713 {
02714         switch (param->cmd) {
02715         case PRISM2_HOSTAPD_FLUSH:
02716                 ap_control_kickall(ap);
02717                 return 0;
02718         case PRISM2_HOSTAPD_ADD_STA:
02719                 return prism2_hostapd_add_sta(ap, param);
02720         case PRISM2_HOSTAPD_REMOVE_STA:
02721                 return prism2_hostapd_remove_sta(ap, param);
02722         case PRISM2_HOSTAPD_GET_INFO_STA:
02723                 return prism2_hostapd_get_info_sta(ap, param);
02724         case PRISM2_HOSTAPD_SET_FLAGS_STA:
02725                 return prism2_hostapd_set_flags_sta(ap, param);
02726         default:
02727                 printk(KERN_WARNING "prism2_hostapd: unknown cmd=%d\n",
02728                        param->cmd);
02729                 return -EOPNOTSUPP;
02730         }
02731 }
02732 
02733 
02734 /* Update station info for host-based TX rate control and return current
02735  * TX rate */
02736 static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
02737 {
02738         int ret = sta->tx_rate;
02739         struct hostap_interface *iface = dev->priv;
02740         local_info_t *local = iface->local;
02741 
02742         sta->tx_count[sta->tx_rate_idx]++;
02743         sta->tx_since_last_failure++;
02744         sta->tx_consecutive_exc = 0;
02745         if (sta->tx_since_last_failure >= WLAN_RATE_UPDATE_COUNT &&
02746             sta->tx_rate_idx < sta->tx_max_rate) {
02747                 /* use next higher rate */
02748                 int old_rate, new_rate;
02749                 old_rate = new_rate = sta->tx_rate_idx;
02750                 while (new_rate < sta->tx_max_rate) {
02751                         new_rate++;
02752                         if (ap_tx_rate_ok(new_rate, sta, local)) {
02753                                 sta->tx_rate_idx = new_rate;
02754                                 break;
02755                         }
02756                 }
02757                 if (old_rate != sta->tx_rate_idx) {
02758                         switch (sta->tx_rate_idx) {
02759                         case 0: sta->tx_rate = 10; break;
02760                         case 1: sta->tx_rate = 20; break;
02761                         case 2: sta->tx_rate = 55; break;
02762                         case 3: sta->tx_rate = 110; break;
02763                         default: sta->tx_rate = 0; break;
02764                         }
02765                         PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate raised to"
02766                                " %d\n", dev->name, MAC2STR(sta->addr),
02767                                sta->tx_rate);
02768                 }
02769                 sta->tx_since_last_failure = 0;
02770         }
02771 
02772         return ret;
02773 }
02774 
02775 
02776 /* Called only from software IRQ. Called for each TX frame prior possible
02777  * encryption and transmit. */
02778 ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct sk_buff *skb,
02779                                struct hfa384x_tx_frame *txdesc, int wds,
02780                                int host_encrypt,
02781                                struct prism2_crypt_data **crypt,
02782                                void **sta_ptr)
02783 {
02784         struct sta_info *sta = NULL;
02785         int set_tim, ret;
02786 
02787         ret = AP_TX_CONTINUE;
02788         if (local->ap == NULL)
02789                 goto out;
02790 
02791         if (txdesc->addr1[0] & 0x01) {
02792                 /* broadcast/multicast frame - no AP related processing */
02793                 goto out;
02794         }
02795 
02796         /* unicast packet - check whether destination STA is associated */
02797         spin_lock(&local->ap->sta_table_lock);
02798         sta = ap_get_sta(local->ap, txdesc->addr1);
02799         if (sta)
02800                 atomic_inc(&sta->users);
02801         spin_unlock(&local->ap->sta_table_lock);
02802 
02803         if (local->iw_mode == IW_MODE_MASTER && sta == NULL && !wds) {
02804                 printk(KERN_DEBUG "AP: drop packet to non-associated STA "
02805                        MACSTR "\n", MAC2STR(txdesc->addr1));
02806                 ret = AP_TX_DROP;
02807                 goto out;
02808         }
02809 
02810         if (sta == NULL)
02811                 goto out;
02812 
02813         if (!(sta->flags & WLAN_STA_AUTHORIZED))
02814                 ret = AP_TX_CONTINUE_NOT_AUTHORIZED;
02815 
02816         /* Set tx_rate if using host-based TX rate control */
02817         if (!local->fw_tx_rate_control)
02818                 local->ap->last_tx_rate = txdesc->tx_rate =
02819                         ap_update_sta_tx_rate(sta, local->dev);
02820 
02821         if (local->iw_mode != IW_MODE_MASTER)
02822                 goto out;
02823 
02824         if (!(sta->flags & WLAN_STA_PS))
02825                 goto out;
02826 
02827         if (memcmp(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN) == 0) {
02828                 if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_ADD_MOREDATA) {
02829                         /* indicate to STA that more frames follow */
02830                         txdesc->frame_control |=
02831                                 __constant_cpu_to_le16(WLAN_FC_MOREDATA);
02832                 }
02833 
02834                 if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_BUFFERED_FRAME) {
02835                         /* packet was already buffered and now send due to
02836                          * PS poll, so do not rebuffer it */
02837                         goto out;
02838                 }
02839         }
02840 
02841         if (skb->len == 0 && skb->protocol == __constant_htons(ETH_P_HOSTAP) &&
02842             skb_headroom(skb) >= sizeof(*txdesc)) {
02843                 /* Copy original TX desc back to the skb so that prism2_tx()
02844                  * is able to send it when STA wakes up. */
02845                 memcpy(skb_push(skb, sizeof(*txdesc)),
02846                        txdesc, sizeof(*txdesc));
02847         }
02848         if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) {
02849                 PDEBUG(DEBUG_PS, "%s: No more space in STA (" MACSTR ")'s PS "
02850                        "mode buffer\n", local->dev->name, MAC2STR(sta->addr));
02851                 /* Make sure that TIM is set for the station (it might not be
02852                  * after AP wlan hw reset). */
02853                 hostap_set_tim(local, sta->aid, 1);
02854                 sta->flags |= WLAN_STA_TIM;
02855                 ret = AP_TX_DROP;
02856                 goto out;
02857         }
02858 
02859         /* STA in PS mode, buffer frame for later delivery */
02860         set_tim = skb_queue_empty(&sta->tx_buf);
02861         skb_queue_tail(&sta->tx_buf, skb);
02862         /* FIX: could save RX time to skb and expire buffered frames after
02863          * some time if STA does not poll for them */
02864 
02865         if (set_tim) {
02866                 if (sta->flags & WLAN_STA_TIM)
02867                         PDEBUG(DEBUG_PS2, "Re-setting TIM for aid %d\n",
02868                                sta->aid);
02869                 hostap_set_tim(local, sta->aid, 1);
02870                 sta->flags |= WLAN_STA_TIM;
02871         }
02872 
02873         ret = AP_TX_BUFFERED;
02874 
02875  out:
02876         if (sta != NULL) {
02877                 if (ret == AP_TX_CONTINUE ||
02878                     ret == AP_TX_CONTINUE_NOT_AUTHORIZED) {
02879                         sta->tx_packets++;
02880                         sta->tx_bytes += le16_to_cpu(txdesc->data_len) + 36;
02881                         sta->last_tx = jiffies;
02882                 }
02883 
02884                 if ((ret == AP_TX_CONTINUE ||
02885                      ret == AP_TX_CONTINUE_NOT_AUTHORIZED) &&
02886                     sta->crypt && host_encrypt) {
02887                         *crypt = sta->crypt;
02888                         *sta_ptr = sta; /* hostap_handle_sta_release() will be
02889                                          * called to release sta info later */
02890                 } else
02891                         atomic_dec(&sta->users);
02892         }
02893 
02894         return ret;
02895 }
02896 
02897 
02898 void hostap_handle_sta_release(void *ptr)
02899 {
02900         struct sta_info *sta = ptr;
02901         atomic_dec(&sta->users);
02902 }
02903 
02904 
02905 /* Called only as a tasklet (software IRQ) */
02906 void hostap_handle_sta_tx_exc(local_info_t *local,
02907                               struct hfa384x_tx_frame *txdesc)
02908 {
02909         struct sta_info *sta;
02910 
02911         spin_lock(&local->ap->sta_table_lock);
02912         /* FIX: is addr1 correct for all frame types? */
02913         sta = ap_get_sta(local->ap, txdesc->addr1);
02914         if (!sta) {
02915                 spin_unlock(&local->ap->sta_table_lock);
02916                 PDEBUG(DEBUG_AP, "%s: Could not find STA " MACSTR " for this "
02917                        "TX error (@%lu)\n",
02918                        local->dev->name, MAC2STR(txdesc->addr1), jiffies);
02919                 return;
02920         }
02921 
02922         sta->tx_since_last_failure = 0;
02923         sta->tx_consecutive_exc++;
02924         
02925         if (sta->tx_consecutive_exc >= WLAN_RATE_DECREASE_THRESHOLD &&
02926             sta->tx_rate_idx > 0 && txdesc->tx_rate <= sta->tx_rate) {
02927                 /* use next lower rate */
02928                 int old, rate;
02929                 old = rate = sta->tx_rate_idx;
02930                 while (rate > 0) {
02931                         rate--;
02932                         if (ap_tx_rate_ok(rate, sta, local)) {
02933                                 sta->tx_rate_idx = rate;
02934                                 break;
02935                         }
02936                 }
02937                 if (old != sta->tx_rate_idx) {
02938                         switch (sta->tx_rate_idx) {
02939                         case 0: sta->tx_rate = 10; break;
02940                         case 1: sta->tx_rate = 20; break;
02941                         case 2: sta->tx_rate = 55; break;
02942                         case 3: sta->tx_rate = 110; break;
02943                         default: sta->tx_rate = 0; break;
02944                         }
02945                         PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate lowered "
02946                                "to %d\n", local->dev->name, MAC2STR(sta->addr),
02947                                sta->tx_rate);
02948                 }
02949                 sta->tx_consecutive_exc = 0;
02950         }
02951         spin_unlock(&local->ap->sta_table_lock);
02952 }
02953 
02954 
02955 static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
02956                                   int pwrmgt, int type, int stype)
02957 {
02958         if (pwrmgt && !(sta->flags & WLAN_STA_PS)) {
02959                 sta->flags |= WLAN_STA_PS;
02960                 PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to use PS "
02961                        "mode (type=0x%02X, stype=0x%02X)\n",
02962                        MAC2STR(sta->addr), type, stype);
02963         } else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) {
02964                 sta->flags &= ~WLAN_STA_PS;
02965                 PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to not use "
02966                        "PS mode (type=0x%02X, stype=0x%02X)\n",
02967                        MAC2STR(sta->addr), type, stype);
02968                 if (type != WLAN_FC_TYPE_CTRL || stype != WLAN_FC_STYPE_PSPOLL)
02969                         schedule_packet_send(local, sta);
02970         }
02971 }
02972 
02973 
02974 /* Called only as a tasklet (software IRQ). Called for each RX frame to update
02975  * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */
02976 int hostap_update_sta_ps(local_info_t *local, struct hostap_ieee80211_hdr *hdr)
02977 {
02978         struct sta_info *sta;
02979         u16 fc;
02980 
02981         spin_lock(&local->ap->sta_table_lock);
02982         sta = ap_get_sta(local->ap, hdr->addr2);
02983         if (sta)
02984                 atomic_inc(&sta->users);
02985         spin_unlock(&local->ap->sta_table_lock);
02986 
02987         if (!sta)
02988                 return -1;
02989 
02990         fc = le16_to_cpu(hdr->frame_control);
02991         hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT,
02992                               WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));
02993 
02994         atomic_dec(&sta->users);
02995         return 0;
02996 }
02997 
02998 
02999 /* Called only as a tasklet (software IRQ). Called for each RX frame after
03000  * getting RX header and payload from hardware. */
03001 ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
03002                                struct sk_buff *skb,
03003                                struct hostap_80211_rx_status *rx_stats,
03004                                int wds)
03005 {
03006         int ret;
03007         struct sta_info *sta;
03008         u16 fc, type, stype;
03009         struct hostap_ieee80211_hdr *hdr;
03010 
03011         if (local->ap == NULL)
03012                 return AP_RX_CONTINUE;
03013 
03014         hdr = (struct hostap_ieee80211_hdr *) skb->data;
03015 
03016         fc = le16_to_cpu(hdr->frame_control);
03017         type = WLAN_FC_GET_TYPE(fc);
03018         stype = WLAN_FC_GET_STYPE(fc);
03019 
03020         spin_lock(&local->ap->sta_table_lock);
03021         sta = ap_get_sta(local->ap, hdr->addr2);
03022         if (sta)
03023                 atomic_inc(&sta->users);
03024         spin_unlock(&local->ap->sta_table_lock);
03025 
03026         if (sta && !(sta->flags & WLAN_STA_AUTHORIZED))
03027                 ret = AP_RX_CONTINUE_NOT_AUTHORIZED;
03028         else
03029                 ret = AP_RX_CONTINUE;
03030 
03031 
03032         if (fc & WLAN_FC_TODS) {
03033                 if (!wds && (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
03034                         if (local->hostapd) {
03035                                 prism2_rx_80211(local->apdev, skb, rx_stats,
03036                                                 PRISM2_RX_NON_ASSOC);
03037 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
03038                         } else {
03039                                 printk(KERN_DEBUG "%s: dropped received packet"
03040                                        " from non-associated STA " MACSTR
03041                                        " (type=0x%02x, subtype=0x%02x)\n",
03042                                        dev->name, MAC2STR(hdr->addr2), type,
03043                                        stype);
03044                                 hostap_rx(dev, skb, rx_stats);
03045 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
03046                         }
03047                         ret = AP_RX_EXIT;
03048                         goto out;
03049                 }
03050         } else if (fc & WLAN_FC_FROMDS) {
03051                 if (!wds) {
03052                         /* FromDS frame - not for us; probably
03053                          * broadcast/multicast in another BSS - drop */
03054                         if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
03055                                 printk(KERN_DEBUG "Odd.. FromDS packet "
03056                                        "received with own BSSID\n");
03057                                 hostap_dump_rx_80211(dev->name, skb, rx_stats);
03058                         }
03059                         ret = AP_RX_DROP;
03060                         goto out;
03061                 }
03062         } else if (stype == WLAN_FC_STYPE_NULLFUNC && sta == NULL &&
03063                    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
03064 
03065                 if (local->hostapd) {
03066                         prism2_rx_80211(local->apdev, skb, rx_stats,
03067                                         PRISM2_RX_NON_ASSOC);
03068 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
03069                 } else {
03070                         /* At least Lucent f/w seems to send data::nullfunc
03071                          * frames with no ToDS flag when the current AP returns
03072                          * after being unavailable for some time. Speed up
03073                          * re-association by informing the station about it not
03074                          * being associated. */
03075                         printk(KERN_DEBUG "%s: rejected received nullfunc "
03076                                "frame without ToDS from not associated STA "
03077                                MACSTR "\n",
03078                                dev->name, MAC2STR(hdr->addr2));
03079                         hostap_rx(dev, skb, rx_stats);
03080 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
03081                 }
03082                 ret = AP_RX_EXIT;
03083                 goto out;
03084         } else if (stype == WLAN_FC_STYPE_NULLFUNC) {
03085                 /* At least Lucent cards seem to send periodic nullfunc
03086                  * frames with ToDS. Let these through to update SQ
03087                  * stats and PS state. Nullfunc frames do not contain
03088                  * any data and they will be dropped below. */
03089         } else {
03090                 /* If BSSID (Addr3) is foreign, this frame is a normal
03091                  * broadcast frame from an IBSS network. Drop it silently.
03092                  * If BSSID is own, report the dropping of this frame. */
03093                 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
03094                         printk(KERN_DEBUG "%s: dropped received packet from "
03095                                MACSTR " with no ToDS flag (type=0x%02x, "
03096                                "subtype=0x%02x)\n", dev->name,
03097                                MAC2STR(hdr->addr2), type, stype);
03098                         hostap_dump_rx_80211(dev->name, skb, rx_stats);
03099                 }
03100                 ret = AP_RX_DROP;
03101                 goto out;
03102         }
03103 
03104         if (sta) {
03105                 hostap_ap_update_sq(sta, rx_stats);
03106 
03107                 hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT,
03108                                       type, stype);
03109 
03110                 sta->rx_packets++;
03111                 sta->rx_bytes += skb->len;
03112                 sta->last_rx = jiffies;
03113         }
03114 
03115         if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC &&
03116             fc & WLAN_FC_TODS) {
03117                 if (local->hostapd) {
03118                         prism2_rx_80211(local->apdev, skb, rx_stats,
03119                                         PRISM2_RX_NULLFUNC_ACK);
03120 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
03121                 } else {
03122                         /* some STA f/w's seem to require control::ACK frame
03123                          * for data::nullfunc, but Prism2 f/w 0.8.0 (at least
03124                          * from Compaq) does not send this.. Try to generate
03125                          * ACK for these frames from the host driver to make
03126                          * power saving work with, e.g., Lucent WaveLAN f/w */
03127                         hostap_rx(dev, skb, rx_stats);
03128 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
03129                 }
03130                 ret = AP_RX_EXIT;
03131                 goto out;
03132         }
03133 
03134  out:
03135         if (sta)
03136                 atomic_dec(&sta->users);
03137 
03138         return ret;
03139 }
03140 
03141 
03142 /* Called only as a tasklet (software IRQ) */
03143 int hostap_handle_sta_crypto(local_info_t *local,
03144                              struct hostap_ieee80211_hdr *hdr,
03145                              struct prism2_crypt_data **crypt, void **sta_ptr)
03146 {
03147         struct sta_info *sta;
03148 
03149         spin_lock(&local->ap->sta_table_lock);
03150         sta = ap_get_sta(local->ap, hdr->addr2);
03151         if (sta)
03152                 atomic_inc(&sta->users);
03153         spin_unlock(&local->ap->sta_table_lock);
03154 
03155         if (!sta)
03156                 return -1;
03157 
03158         if (sta->crypt) {
03159                 *crypt = sta->crypt;
03160                 *sta_ptr = sta;
03161                 /* hostap_handle_sta_release() will be called to release STA
03162                  * info */
03163         } else
03164                 atomic_dec(&sta->users);
03165 
03166         return 0;
03167 }
03168 
03169 
03170 /* Called only as a tasklet (software IRQ) */
03171 int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr)
03172 {
03173         struct sta_info *sta;
03174         int ret = 0;
03175 
03176         spin_lock(&ap->sta_table_lock);
03177         sta = ap_get_sta(ap, sta_addr);
03178         if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap)
03179                 ret = 1;
03180         spin_unlock(&ap->sta_table_lock);
03181 
03182         return ret;
03183 }
03184 
03185 
03186 /* Called only as a tasklet (software IRQ) */
03187 int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
03188 {
03189         struct sta_info *sta;
03190         int ret = 1;
03191 
03192         if (!ap)
03193                 return -1;
03194 
03195         spin_lock(&ap->sta_table_lock);
03196         sta = ap_get_sta(ap, sta_addr);
03197         if (sta)
03198                 ret = 0;
03199         spin_unlock(&ap->sta_table_lock);
03200 
03201         if (ret == 1) {
03202                 sta = ap_add_sta(ap, sta_addr);
03203                 if (!sta)
03204                         ret = -1;
03205                 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
03206                 sta->ap = 1;
03207                 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
03208                 /* No way of knowing which rates are supported since we did not
03209                  * get supported rates element from beacon/assoc req. Assume
03210                  * that remote end supports all 802.11b rates. */
03211                 sta->supported_rates[0] = 0x82;
03212                 sta->supported_rates[1] = 0x84;
03213                 sta->supported_rates[2] = 0x0b;
03214                 sta->supported_rates[3] = 0x16;
03215                 sta->tx_supp_rates = WLAN_RATE_1M | WLAN_RATE_2M |
03216                         WLAN_RATE_5M5 | WLAN_RATE_11M;
03217                 sta->tx_rate = 110;
03218                 sta->tx_max_rate = sta->tx_rate_idx = 3;
03219         }
03220 
03221         return ret;
03222 }
03223 
03224 
03225 /* Called only as a tasklet (software IRQ) */
03226 int hostap_update_rx_stats(struct ap_data *ap,
03227                            struct hostap_ieee80211_hdr *hdr,
03228                            struct hostap_80211_rx_status *rx_stats)
03229 {
03230         struct sta_info *sta;
03231 
03232         if (!ap)
03233                 return -1;
03234 
03235         spin_lock(&ap->sta_table_lock);
03236         sta = ap_get_sta(ap, hdr->addr2);
03237         if (sta)
03238                 hostap_ap_update_sq(sta, rx_stats);
03239         spin_unlock(&ap->sta_table_lock);
03240 
03241         return sta ? 0 : -1;
03242 }
03243 
03244 
03245 void hostap_update_rates(local_info_t *local)
03246 {
03247         struct list_head *ptr;
03248         struct ap_data *ap = local->ap;
03249 
03250         if (!ap)
03251                 return;
03252 
03253         spin_lock_bh(&ap->sta_table_lock);
03254         for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
03255                 struct sta_info *sta = (struct sta_info *) ptr;
03256                 prism2_check_tx_rates(sta);
03257         }
03258         spin_unlock_bh(&ap->sta_table_lock);
03259 }
03260 
03261 
03262 static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
03263                                 struct prism2_crypt_data ***crypt)
03264 {
03265         struct sta_info *sta;
03266 
03267         spin_lock_bh(&ap->sta_table_lock);
03268         sta = ap_get_sta(ap, addr);
03269         if (sta)
03270                 atomic_inc(&sta->users);
03271         spin_unlock_bh(&ap->sta_table_lock);
03272 
03273         if (!sta && permanent)
03274                 sta = ap_add_sta(ap, addr);
03275 
03276         if (!sta)
03277                 return NULL;
03278 
03279         if (permanent)
03280                 sta->flags |= WLAN_STA_PERM;
03281 
03282         *crypt = &sta->crypt;
03283 
03284         return sta;
03285 }
03286 
03287 
03288 void hostap_add_wds_links(local_info_t *local)
03289 {
03290         struct ap_data *ap = local->ap;
03291         struct list_head *ptr;
03292 
03293         spin_lock_bh(&ap->sta_table_lock);
03294         list_for_each(ptr, &ap->sta_list) {
03295                 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
03296                 if (sta->ap)
03297                         hostap_wds_link_oper(local, sta->addr, WDS_ADD);
03298         }
03299         spin_unlock_bh(&ap->sta_table_lock);
03300 
03301         PRISM2_SCHEDULE_TASK(&local->ap->wds_oper_queue);
03302 }
03303 
03304 
03305 void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type)
03306 {
03307         struct wds_oper_data *entry;
03308 
03309         entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
03310         if (!entry)
03311                 return;
03312         memcpy(entry->addr, addr, ETH_ALEN);
03313         entry->type = type;
03314         spin_lock_bh(&local->lock);
03315         entry->next = local->ap->wds_oper_entries;
03316         local->ap->wds_oper_entries = entry;
03317         spin_unlock_bh(&local->lock);
03318 
03319         PRISM2_SCHEDULE_TASK(&local->ap->wds_oper_queue);
03320 }
03321 
03322 
03323 EXPORT_SYMBOL(hostap_init_data);
03324 EXPORT_SYMBOL(hostap_free_data);
03325 EXPORT_SYMBOL(hostap_check_sta_fw_version);
03326 EXPORT_SYMBOL(hostap_handle_sta_tx);
03327 EXPORT_SYMBOL(hostap_handle_sta_release);
03328 EXPORT_SYMBOL(hostap_handle_sta_tx_exc);
03329 EXPORT_SYMBOL(hostap_update_sta_ps);
03330 EXPORT_SYMBOL(hostap_handle_sta_rx);
03331 EXPORT_SYMBOL(hostap_is_sta_assoc);
03332 EXPORT_SYMBOL(hostap_add_sta);
03333 EXPORT_SYMBOL(hostap_update_rates);
03334 EXPORT_SYMBOL(hostap_add_wds_links);
03335 EXPORT_SYMBOL(hostap_wds_link_oper);
03336 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
03337 EXPORT_SYMBOL(hostap_deauth_all_stas);
03338 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

Generated on Mon Nov 21 15:58:09 2005 for openwifi by  doxygen 1.4.1