00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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
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
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
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
00323
00324
00325
00326
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
00383
00384
00385
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
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
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
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
00688
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
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
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
00836
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
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
00891
00892
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
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
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
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
00980
00981 ap->initialized = 0;
00982 }
00983
00984
00985
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
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
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);
01040 if (type == WLAN_FC_TYPE_DATA) {
01041 fc |= WLAN_FC_FROMDS;
01042 memcpy(txdesc->addr2, dev->dev_addr, ETH_ALEN);
01043 memcpy(txdesc->addr3, dev->dev_addr, ETH_ALEN);
01044 } else if (type == WLAN_FC_TYPE_CTRL) {
01045
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);
01050 memcpy(txdesc->addr3, dev->dev_addr, ETH_ALEN);
01051 }
01052
01053 txdesc->frame_control = cpu_to_le16(fc);
01054
01055
01056
01057
01058
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
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
01076
01077
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
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
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
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
01205
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
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
01319
01320
01321
01322
01323
01324
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
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
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
01512
01513
01514
01515
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
01542
01543
01544
01545
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);
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
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;
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
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
01734
01735
01736
01737 *pos = __constant_cpu_to_le16(WLAN_CAPABILITY_ESS);
01738 pos++;
01739
01740
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));
01746 pos++;
01747
01748
01749 p = (char *) pos;
01750 *p++ = WLAN_EID_SUPP_RATES;
01751 lpos = p;
01752 *p++ = 0;
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
01786
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
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
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
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
01893
01894
01895
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
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
01936
01937
01938
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
01944
01945 dev_queue_xmit(skb);
01946 return;
01947 }
01948
01949
01950
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
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
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
02016
02017
02018
02019
02020
02021
02022
02023
02024 while ((skb = skb_dequeue(&sta->tx_buf)) != NULL) {
02025
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
02033
02034
02035
02036 break;
02037 }
02038 }
02039
02040 if (skb_queue_empty(&sta->tx_buf)) {
02041
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
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
02132 pos += 4; left -= 8;
02133
02134 beacon_int = __le16_to_cpu(*pos);
02135 pos++; left -= 2;
02136
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
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
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
02224
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
02259
02260
02261
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
02268 u16 fc, type, stype;
02269 struct hostap_ieee80211_hdr *hdr;
02270
02271
02272
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
02285
02286
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
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
02374
02375 done:
02376 dev_kfree_skb(skb);
02377 }
02378
02379
02380
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
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
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
02490
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
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
02520
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
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 );
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
02590 }
02591 #endif
02592
02593 sta->last_rx_updated = 0;
02594
02595
02596 }
02597
02598 spin_unlock_bh(&ap->sta_table_lock);
02599
02600 return current_ev - buffer;
02601 }
02602 #endif
02603 #endif
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
02735
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
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
02777
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
02793 goto out;
02794 }
02795
02796
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
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
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
02836
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
02844
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
02852
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
02860 set_tim = skb_queue_empty(&sta->tx_buf);
02861 skb_queue_tail(&sta->tx_buf, skb);
02862
02863
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;
02889
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
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
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
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
02975
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
03000
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
03046 }
03047 ret = AP_RX_EXIT;
03048 goto out;
03049 }
03050 } else if (fc & WLAN_FC_FROMDS) {
03051 if (!wds) {
03052
03053
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
03071
03072
03073
03074
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
03081 }
03082 ret = AP_RX_EXIT;
03083 goto out;
03084 } else if (stype == WLAN_FC_STYPE_NULLFUNC) {
03085
03086
03087
03088
03089 } else {
03090
03091
03092
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
03123
03124
03125
03126
03127 hostap_rx(dev, skb, rx_stats);
03128 #endif
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
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
03162
03163 } else
03164 atomic_dec(&sta->users);
03165
03166 return 0;
03167 }
03168
03169
03170
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
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
03209
03210
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
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