Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.29-rc8 1172 lines 28 kB view raw
1/* 2 * mac80211 configuration hooks for cfg80211 3 * 4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 5 * 6 * This file is GPLv2 as found in COPYING. 7 */ 8 9#include <linux/ieee80211.h> 10#include <linux/nl80211.h> 11#include <linux/rtnetlink.h> 12#include <net/net_namespace.h> 13#include <linux/rcupdate.h> 14#include <net/cfg80211.h> 15#include "ieee80211_i.h" 16#include "cfg.h" 17#include "rate.h" 18#include "mesh.h" 19 20static bool nl80211_type_check(enum nl80211_iftype type) 21{ 22 switch (type) { 23 case NL80211_IFTYPE_ADHOC: 24 case NL80211_IFTYPE_STATION: 25 case NL80211_IFTYPE_MONITOR: 26#ifdef CONFIG_MAC80211_MESH 27 case NL80211_IFTYPE_MESH_POINT: 28#endif 29 case NL80211_IFTYPE_AP: 30 case NL80211_IFTYPE_AP_VLAN: 31 case NL80211_IFTYPE_WDS: 32 return true; 33 default: 34 return false; 35 } 36} 37 38static int ieee80211_add_iface(struct wiphy *wiphy, char *name, 39 enum nl80211_iftype type, u32 *flags, 40 struct vif_params *params) 41{ 42 struct ieee80211_local *local = wiphy_priv(wiphy); 43 struct net_device *dev; 44 struct ieee80211_sub_if_data *sdata; 45 int err; 46 47 if (!nl80211_type_check(type)) 48 return -EINVAL; 49 50 err = ieee80211_if_add(local, name, &dev, type, params); 51 if (err || type != NL80211_IFTYPE_MONITOR || !flags) 52 return err; 53 54 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 55 sdata->u.mntr_flags = *flags; 56 return 0; 57} 58 59static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) 60{ 61 struct net_device *dev; 62 struct ieee80211_sub_if_data *sdata; 63 64 /* we're under RTNL */ 65 dev = __dev_get_by_index(&init_net, ifindex); 66 if (!dev) 67 return -ENODEV; 68 69 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 70 71 ieee80211_if_remove(sdata); 72 73 return 0; 74} 75 76static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, 77 enum nl80211_iftype type, u32 *flags, 78 struct vif_params *params) 79{ 80 struct net_device *dev; 81 struct ieee80211_sub_if_data *sdata; 82 int ret; 83 84 /* we're under RTNL */ 85 dev = __dev_get_by_index(&init_net, ifindex); 86 if (!dev) 87 return -ENODEV; 88 89 if (!nl80211_type_check(type)) 90 return -EINVAL; 91 92 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 93 94 ret = ieee80211_if_change_type(sdata, type); 95 if (ret) 96 return ret; 97 98 if (netif_running(sdata->dev)) 99 return -EBUSY; 100 101 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) 102 ieee80211_sdata_set_mesh_id(sdata, 103 params->mesh_id_len, 104 params->mesh_id); 105 106 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) 107 return 0; 108 109 sdata->u.mntr_flags = *flags; 110 return 0; 111} 112 113static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 114 u8 key_idx, u8 *mac_addr, 115 struct key_params *params) 116{ 117 struct ieee80211_sub_if_data *sdata; 118 struct sta_info *sta = NULL; 119 enum ieee80211_key_alg alg; 120 struct ieee80211_key *key; 121 int err; 122 123 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 124 125 switch (params->cipher) { 126 case WLAN_CIPHER_SUITE_WEP40: 127 case WLAN_CIPHER_SUITE_WEP104: 128 alg = ALG_WEP; 129 break; 130 case WLAN_CIPHER_SUITE_TKIP: 131 alg = ALG_TKIP; 132 break; 133 case WLAN_CIPHER_SUITE_CCMP: 134 alg = ALG_CCMP; 135 break; 136 default: 137 return -EINVAL; 138 } 139 140 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key); 141 if (!key) 142 return -ENOMEM; 143 144 rcu_read_lock(); 145 146 if (mac_addr) { 147 sta = sta_info_get(sdata->local, mac_addr); 148 if (!sta) { 149 ieee80211_key_free(key); 150 err = -ENOENT; 151 goto out_unlock; 152 } 153 } 154 155 ieee80211_key_link(key, sdata, sta); 156 157 err = 0; 158 out_unlock: 159 rcu_read_unlock(); 160 161 return err; 162} 163 164static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 165 u8 key_idx, u8 *mac_addr) 166{ 167 struct ieee80211_sub_if_data *sdata; 168 struct sta_info *sta; 169 int ret; 170 171 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 172 173 rcu_read_lock(); 174 175 if (mac_addr) { 176 ret = -ENOENT; 177 178 sta = sta_info_get(sdata->local, mac_addr); 179 if (!sta) 180 goto out_unlock; 181 182 if (sta->key) { 183 ieee80211_key_free(sta->key); 184 WARN_ON(sta->key); 185 ret = 0; 186 } 187 188 goto out_unlock; 189 } 190 191 if (!sdata->keys[key_idx]) { 192 ret = -ENOENT; 193 goto out_unlock; 194 } 195 196 ieee80211_key_free(sdata->keys[key_idx]); 197 WARN_ON(sdata->keys[key_idx]); 198 199 ret = 0; 200 out_unlock: 201 rcu_read_unlock(); 202 203 return ret; 204} 205 206static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 207 u8 key_idx, u8 *mac_addr, void *cookie, 208 void (*callback)(void *cookie, 209 struct key_params *params)) 210{ 211 struct ieee80211_sub_if_data *sdata; 212 struct sta_info *sta = NULL; 213 u8 seq[6] = {0}; 214 struct key_params params; 215 struct ieee80211_key *key; 216 u32 iv32; 217 u16 iv16; 218 int err = -ENOENT; 219 220 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 221 222 rcu_read_lock(); 223 224 if (mac_addr) { 225 sta = sta_info_get(sdata->local, mac_addr); 226 if (!sta) 227 goto out; 228 229 key = sta->key; 230 } else 231 key = sdata->keys[key_idx]; 232 233 if (!key) 234 goto out; 235 236 memset(&params, 0, sizeof(params)); 237 238 switch (key->conf.alg) { 239 case ALG_TKIP: 240 params.cipher = WLAN_CIPHER_SUITE_TKIP; 241 242 iv32 = key->u.tkip.tx.iv32; 243 iv16 = key->u.tkip.tx.iv16; 244 245 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && 246 sdata->local->ops->get_tkip_seq) 247 sdata->local->ops->get_tkip_seq( 248 local_to_hw(sdata->local), 249 key->conf.hw_key_idx, 250 &iv32, &iv16); 251 252 seq[0] = iv16 & 0xff; 253 seq[1] = (iv16 >> 8) & 0xff; 254 seq[2] = iv32 & 0xff; 255 seq[3] = (iv32 >> 8) & 0xff; 256 seq[4] = (iv32 >> 16) & 0xff; 257 seq[5] = (iv32 >> 24) & 0xff; 258 params.seq = seq; 259 params.seq_len = 6; 260 break; 261 case ALG_CCMP: 262 params.cipher = WLAN_CIPHER_SUITE_CCMP; 263 seq[0] = key->u.ccmp.tx_pn[5]; 264 seq[1] = key->u.ccmp.tx_pn[4]; 265 seq[2] = key->u.ccmp.tx_pn[3]; 266 seq[3] = key->u.ccmp.tx_pn[2]; 267 seq[4] = key->u.ccmp.tx_pn[1]; 268 seq[5] = key->u.ccmp.tx_pn[0]; 269 params.seq = seq; 270 params.seq_len = 6; 271 break; 272 case ALG_WEP: 273 if (key->conf.keylen == 5) 274 params.cipher = WLAN_CIPHER_SUITE_WEP40; 275 else 276 params.cipher = WLAN_CIPHER_SUITE_WEP104; 277 break; 278 } 279 280 params.key = key->conf.key; 281 params.key_len = key->conf.keylen; 282 283 callback(cookie, &params); 284 err = 0; 285 286 out: 287 rcu_read_unlock(); 288 return err; 289} 290 291static int ieee80211_config_default_key(struct wiphy *wiphy, 292 struct net_device *dev, 293 u8 key_idx) 294{ 295 struct ieee80211_sub_if_data *sdata; 296 297 rcu_read_lock(); 298 299 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 300 ieee80211_set_default_key(sdata, key_idx); 301 302 rcu_read_unlock(); 303 304 return 0; 305} 306 307static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 308{ 309 struct ieee80211_sub_if_data *sdata = sta->sdata; 310 311 sinfo->filled = STATION_INFO_INACTIVE_TIME | 312 STATION_INFO_RX_BYTES | 313 STATION_INFO_TX_BYTES | 314 STATION_INFO_TX_BITRATE; 315 316 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 317 sinfo->rx_bytes = sta->rx_bytes; 318 sinfo->tx_bytes = sta->tx_bytes; 319 320 if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { 321 sinfo->filled |= STATION_INFO_SIGNAL; 322 sinfo->signal = (s8)sta->last_signal; 323 } 324 325 sinfo->txrate.flags = 0; 326 if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) 327 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; 328 if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 329 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 330 if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI) 331 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 332 333 if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) { 334 struct ieee80211_supported_band *sband; 335 sband = sta->local->hw.wiphy->bands[ 336 sta->local->hw.conf.channel->band]; 337 sinfo->txrate.legacy = 338 sband->bitrates[sta->last_tx_rate.idx].bitrate; 339 } else 340 sinfo->txrate.mcs = sta->last_tx_rate.idx; 341 342 if (ieee80211_vif_is_mesh(&sdata->vif)) { 343#ifdef CONFIG_MAC80211_MESH 344 sinfo->filled |= STATION_INFO_LLID | 345 STATION_INFO_PLID | 346 STATION_INFO_PLINK_STATE; 347 348 sinfo->llid = le16_to_cpu(sta->llid); 349 sinfo->plid = le16_to_cpu(sta->plid); 350 sinfo->plink_state = sta->plink_state; 351#endif 352 } 353} 354 355 356static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, 357 int idx, u8 *mac, struct station_info *sinfo) 358{ 359 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 360 struct sta_info *sta; 361 int ret = -ENOENT; 362 363 rcu_read_lock(); 364 365 sta = sta_info_get_by_idx(local, idx, dev); 366 if (sta) { 367 ret = 0; 368 memcpy(mac, sta->sta.addr, ETH_ALEN); 369 sta_set_sinfo(sta, sinfo); 370 } 371 372 rcu_read_unlock(); 373 374 return ret; 375} 376 377static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 378 u8 *mac, struct station_info *sinfo) 379{ 380 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 381 struct sta_info *sta; 382 int ret = -ENOENT; 383 384 rcu_read_lock(); 385 386 /* XXX: verify sta->dev == dev */ 387 388 sta = sta_info_get(local, mac); 389 if (sta) { 390 ret = 0; 391 sta_set_sinfo(sta, sinfo); 392 } 393 394 rcu_read_unlock(); 395 396 return ret; 397} 398 399/* 400 * This handles both adding a beacon and setting new beacon info 401 */ 402static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, 403 struct beacon_parameters *params) 404{ 405 struct beacon_data *new, *old; 406 int new_head_len, new_tail_len; 407 int size; 408 int err = -EINVAL; 409 410 old = sdata->u.ap.beacon; 411 412 /* head must not be zero-length */ 413 if (params->head && !params->head_len) 414 return -EINVAL; 415 416 /* 417 * This is a kludge. beacon interval should really be part 418 * of the beacon information. 419 */ 420 if (params->interval) { 421 sdata->local->hw.conf.beacon_int = params->interval; 422 err = ieee80211_hw_config(sdata->local, 423 IEEE80211_CONF_CHANGE_BEACON_INTERVAL); 424 if (err < 0) 425 return err; 426 /* 427 * We updated some parameter so if below bails out 428 * it's not an error. 429 */ 430 err = 0; 431 } 432 433 /* Need to have a beacon head if we don't have one yet */ 434 if (!params->head && !old) 435 return err; 436 437 /* sorry, no way to start beaconing without dtim period */ 438 if (!params->dtim_period && !old) 439 return err; 440 441 /* new or old head? */ 442 if (params->head) 443 new_head_len = params->head_len; 444 else 445 new_head_len = old->head_len; 446 447 /* new or old tail? */ 448 if (params->tail || !old) 449 /* params->tail_len will be zero for !params->tail */ 450 new_tail_len = params->tail_len; 451 else 452 new_tail_len = old->tail_len; 453 454 size = sizeof(*new) + new_head_len + new_tail_len; 455 456 new = kzalloc(size, GFP_KERNEL); 457 if (!new) 458 return -ENOMEM; 459 460 /* start filling the new info now */ 461 462 /* new or old dtim period? */ 463 if (params->dtim_period) 464 new->dtim_period = params->dtim_period; 465 else 466 new->dtim_period = old->dtim_period; 467 468 /* 469 * pointers go into the block we allocated, 470 * memory is | beacon_data | head | tail | 471 */ 472 new->head = ((u8 *) new) + sizeof(*new); 473 new->tail = new->head + new_head_len; 474 new->head_len = new_head_len; 475 new->tail_len = new_tail_len; 476 477 /* copy in head */ 478 if (params->head) 479 memcpy(new->head, params->head, new_head_len); 480 else 481 memcpy(new->head, old->head, new_head_len); 482 483 /* copy in optional tail */ 484 if (params->tail) 485 memcpy(new->tail, params->tail, new_tail_len); 486 else 487 if (old) 488 memcpy(new->tail, old->tail, new_tail_len); 489 490 rcu_assign_pointer(sdata->u.ap.beacon, new); 491 492 synchronize_rcu(); 493 494 kfree(old); 495 496 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 497} 498 499static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 500 struct beacon_parameters *params) 501{ 502 struct ieee80211_sub_if_data *sdata; 503 struct beacon_data *old; 504 505 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 506 507 if (sdata->vif.type != NL80211_IFTYPE_AP) 508 return -EINVAL; 509 510 old = sdata->u.ap.beacon; 511 512 if (old) 513 return -EALREADY; 514 515 return ieee80211_config_beacon(sdata, params); 516} 517 518static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, 519 struct beacon_parameters *params) 520{ 521 struct ieee80211_sub_if_data *sdata; 522 struct beacon_data *old; 523 524 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 525 526 if (sdata->vif.type != NL80211_IFTYPE_AP) 527 return -EINVAL; 528 529 old = sdata->u.ap.beacon; 530 531 if (!old) 532 return -ENOENT; 533 534 return ieee80211_config_beacon(sdata, params); 535} 536 537static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) 538{ 539 struct ieee80211_sub_if_data *sdata; 540 struct beacon_data *old; 541 542 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 543 544 if (sdata->vif.type != NL80211_IFTYPE_AP) 545 return -EINVAL; 546 547 old = sdata->u.ap.beacon; 548 549 if (!old) 550 return -ENOENT; 551 552 rcu_assign_pointer(sdata->u.ap.beacon, NULL); 553 synchronize_rcu(); 554 kfree(old); 555 556 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 557} 558 559/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 560struct iapp_layer2_update { 561 u8 da[ETH_ALEN]; /* broadcast */ 562 u8 sa[ETH_ALEN]; /* STA addr */ 563 __be16 len; /* 6 */ 564 u8 dsap; /* 0 */ 565 u8 ssap; /* 0 */ 566 u8 control; 567 u8 xid_info[3]; 568} __attribute__ ((packed)); 569 570static void ieee80211_send_layer2_update(struct sta_info *sta) 571{ 572 struct iapp_layer2_update *msg; 573 struct sk_buff *skb; 574 575 /* Send Level 2 Update Frame to update forwarding tables in layer 2 576 * bridge devices */ 577 578 skb = dev_alloc_skb(sizeof(*msg)); 579 if (!skb) 580 return; 581 msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg)); 582 583 /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) 584 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ 585 586 memset(msg->da, 0xff, ETH_ALEN); 587 memcpy(msg->sa, sta->sta.addr, ETH_ALEN); 588 msg->len = htons(6); 589 msg->dsap = 0; 590 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ 591 msg->control = 0xaf; /* XID response lsb.1111F101. 592 * F=0 (no poll command; unsolicited frame) */ 593 msg->xid_info[0] = 0x81; /* XID format identifier */ 594 msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ 595 msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */ 596 597 skb->dev = sta->sdata->dev; 598 skb->protocol = eth_type_trans(skb, sta->sdata->dev); 599 memset(skb->cb, 0, sizeof(skb->cb)); 600 netif_rx(skb); 601} 602 603static void sta_apply_parameters(struct ieee80211_local *local, 604 struct sta_info *sta, 605 struct station_parameters *params) 606{ 607 u32 rates; 608 int i, j; 609 struct ieee80211_supported_band *sband; 610 struct ieee80211_sub_if_data *sdata = sta->sdata; 611 612 sband = local->hw.wiphy->bands[local->oper_channel->band]; 613 614 /* 615 * FIXME: updating the flags is racy when this function is 616 * called from ieee80211_change_station(), this will 617 * be resolved in a future patch. 618 */ 619 620 if (params->station_flags & STATION_FLAG_CHANGED) { 621 spin_lock_bh(&sta->lock); 622 sta->flags &= ~WLAN_STA_AUTHORIZED; 623 if (params->station_flags & STATION_FLAG_AUTHORIZED) 624 sta->flags |= WLAN_STA_AUTHORIZED; 625 626 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 627 if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE) 628 sta->flags |= WLAN_STA_SHORT_PREAMBLE; 629 630 sta->flags &= ~WLAN_STA_WME; 631 if (params->station_flags & STATION_FLAG_WME) 632 sta->flags |= WLAN_STA_WME; 633 spin_unlock_bh(&sta->lock); 634 } 635 636 /* 637 * FIXME: updating the following information is racy when this 638 * function is called from ieee80211_change_station(). 639 * However, all this information should be static so 640 * maybe we should just reject attemps to change it. 641 */ 642 643 if (params->aid) { 644 sta->sta.aid = params->aid; 645 if (sta->sta.aid > IEEE80211_MAX_AID) 646 sta->sta.aid = 0; /* XXX: should this be an error? */ 647 } 648 649 if (params->listen_interval >= 0) 650 sta->listen_interval = params->listen_interval; 651 652 if (params->supported_rates) { 653 rates = 0; 654 655 for (i = 0; i < params->supported_rates_len; i++) { 656 int rate = (params->supported_rates[i] & 0x7f) * 5; 657 for (j = 0; j < sband->n_bitrates; j++) { 658 if (sband->bitrates[j].bitrate == rate) 659 rates |= BIT(j); 660 } 661 } 662 sta->sta.supp_rates[local->oper_channel->band] = rates; 663 } 664 665 if (params->ht_capa) 666 ieee80211_ht_cap_ie_to_sta_ht_cap(sband, 667 params->ht_capa, 668 &sta->sta.ht_cap); 669 670 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 671 switch (params->plink_action) { 672 case PLINK_ACTION_OPEN: 673 mesh_plink_open(sta); 674 break; 675 case PLINK_ACTION_BLOCK: 676 mesh_plink_block(sta); 677 break; 678 } 679 } 680} 681 682static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, 683 u8 *mac, struct station_parameters *params) 684{ 685 struct ieee80211_local *local = wiphy_priv(wiphy); 686 struct sta_info *sta; 687 struct ieee80211_sub_if_data *sdata; 688 int err; 689 int layer2_update; 690 691 /* Prevent a race with changing the rate control algorithm */ 692 if (!netif_running(dev)) 693 return -ENETDOWN; 694 695 if (params->vlan) { 696 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 697 698 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 699 sdata->vif.type != NL80211_IFTYPE_AP) 700 return -EINVAL; 701 } else 702 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 703 704 if (compare_ether_addr(mac, dev->dev_addr) == 0) 705 return -EINVAL; 706 707 if (is_multicast_ether_addr(mac)) 708 return -EINVAL; 709 710 sta = sta_info_alloc(sdata, mac, GFP_KERNEL); 711 if (!sta) 712 return -ENOMEM; 713 714 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; 715 716 sta_apply_parameters(local, sta, params); 717 718 rate_control_rate_init(sta); 719 720 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 721 sdata->vif.type == NL80211_IFTYPE_AP; 722 723 rcu_read_lock(); 724 725 err = sta_info_insert(sta); 726 if (err) { 727 /* STA has been freed */ 728 if (err == -EEXIST && layer2_update) { 729 /* Need to update layer 2 devices on reassociation */ 730 sta = sta_info_get(local, mac); 731 if (sta) 732 ieee80211_send_layer2_update(sta); 733 } 734 rcu_read_unlock(); 735 return err; 736 } 737 738 if (layer2_update) 739 ieee80211_send_layer2_update(sta); 740 741 rcu_read_unlock(); 742 743 return 0; 744} 745 746static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, 747 u8 *mac) 748{ 749 struct ieee80211_local *local = wiphy_priv(wiphy); 750 struct ieee80211_sub_if_data *sdata; 751 struct sta_info *sta; 752 753 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 754 755 if (mac) { 756 rcu_read_lock(); 757 758 /* XXX: get sta belonging to dev */ 759 sta = sta_info_get(local, mac); 760 if (!sta) { 761 rcu_read_unlock(); 762 return -ENOENT; 763 } 764 765 sta_info_unlink(&sta); 766 rcu_read_unlock(); 767 768 sta_info_destroy(sta); 769 } else 770 sta_info_flush(local, sdata); 771 772 return 0; 773} 774 775static int ieee80211_change_station(struct wiphy *wiphy, 776 struct net_device *dev, 777 u8 *mac, 778 struct station_parameters *params) 779{ 780 struct ieee80211_local *local = wiphy_priv(wiphy); 781 struct sta_info *sta; 782 struct ieee80211_sub_if_data *vlansdata; 783 784 rcu_read_lock(); 785 786 /* XXX: get sta belonging to dev */ 787 sta = sta_info_get(local, mac); 788 if (!sta) { 789 rcu_read_unlock(); 790 return -ENOENT; 791 } 792 793 if (params->vlan && params->vlan != sta->sdata->dev) { 794 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 795 796 if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN && 797 vlansdata->vif.type != NL80211_IFTYPE_AP) { 798 rcu_read_unlock(); 799 return -EINVAL; 800 } 801 802 sta->sdata = vlansdata; 803 ieee80211_send_layer2_update(sta); 804 } 805 806 sta_apply_parameters(local, sta, params); 807 808 rcu_read_unlock(); 809 810 return 0; 811} 812 813#ifdef CONFIG_MAC80211_MESH 814static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, 815 u8 *dst, u8 *next_hop) 816{ 817 struct ieee80211_local *local = wiphy_priv(wiphy); 818 struct ieee80211_sub_if_data *sdata; 819 struct mesh_path *mpath; 820 struct sta_info *sta; 821 int err; 822 823 if (!netif_running(dev)) 824 return -ENETDOWN; 825 826 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 827 828 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 829 return -ENOTSUPP; 830 831 rcu_read_lock(); 832 sta = sta_info_get(local, next_hop); 833 if (!sta) { 834 rcu_read_unlock(); 835 return -ENOENT; 836 } 837 838 err = mesh_path_add(dst, sdata); 839 if (err) { 840 rcu_read_unlock(); 841 return err; 842 } 843 844 mpath = mesh_path_lookup(dst, sdata); 845 if (!mpath) { 846 rcu_read_unlock(); 847 return -ENXIO; 848 } 849 mesh_path_fix_nexthop(mpath, sta); 850 851 rcu_read_unlock(); 852 return 0; 853} 854 855static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, 856 u8 *dst) 857{ 858 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 859 860 if (dst) 861 return mesh_path_del(dst, sdata); 862 863 mesh_path_flush(sdata); 864 return 0; 865} 866 867static int ieee80211_change_mpath(struct wiphy *wiphy, 868 struct net_device *dev, 869 u8 *dst, u8 *next_hop) 870{ 871 struct ieee80211_local *local = wiphy_priv(wiphy); 872 struct ieee80211_sub_if_data *sdata; 873 struct mesh_path *mpath; 874 struct sta_info *sta; 875 876 if (!netif_running(dev)) 877 return -ENETDOWN; 878 879 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 880 881 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 882 return -ENOTSUPP; 883 884 rcu_read_lock(); 885 886 sta = sta_info_get(local, next_hop); 887 if (!sta) { 888 rcu_read_unlock(); 889 return -ENOENT; 890 } 891 892 mpath = mesh_path_lookup(dst, sdata); 893 if (!mpath) { 894 rcu_read_unlock(); 895 return -ENOENT; 896 } 897 898 mesh_path_fix_nexthop(mpath, sta); 899 900 rcu_read_unlock(); 901 return 0; 902} 903 904static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, 905 struct mpath_info *pinfo) 906{ 907 if (mpath->next_hop) 908 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); 909 else 910 memset(next_hop, 0, ETH_ALEN); 911 912 pinfo->filled = MPATH_INFO_FRAME_QLEN | 913 MPATH_INFO_DSN | 914 MPATH_INFO_METRIC | 915 MPATH_INFO_EXPTIME | 916 MPATH_INFO_DISCOVERY_TIMEOUT | 917 MPATH_INFO_DISCOVERY_RETRIES | 918 MPATH_INFO_FLAGS; 919 920 pinfo->frame_qlen = mpath->frame_queue.qlen; 921 pinfo->dsn = mpath->dsn; 922 pinfo->metric = mpath->metric; 923 if (time_before(jiffies, mpath->exp_time)) 924 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); 925 pinfo->discovery_timeout = 926 jiffies_to_msecs(mpath->discovery_timeout); 927 pinfo->discovery_retries = mpath->discovery_retries; 928 pinfo->flags = 0; 929 if (mpath->flags & MESH_PATH_ACTIVE) 930 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; 931 if (mpath->flags & MESH_PATH_RESOLVING) 932 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 933 if (mpath->flags & MESH_PATH_DSN_VALID) 934 pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID; 935 if (mpath->flags & MESH_PATH_FIXED) 936 pinfo->flags |= NL80211_MPATH_FLAG_FIXED; 937 if (mpath->flags & MESH_PATH_RESOLVING) 938 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 939 940 pinfo->flags = mpath->flags; 941} 942 943static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, 944 u8 *dst, u8 *next_hop, struct mpath_info *pinfo) 945 946{ 947 struct ieee80211_sub_if_data *sdata; 948 struct mesh_path *mpath; 949 950 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 951 952 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 953 return -ENOTSUPP; 954 955 rcu_read_lock(); 956 mpath = mesh_path_lookup(dst, sdata); 957 if (!mpath) { 958 rcu_read_unlock(); 959 return -ENOENT; 960 } 961 memcpy(dst, mpath->dst, ETH_ALEN); 962 mpath_set_pinfo(mpath, next_hop, pinfo); 963 rcu_read_unlock(); 964 return 0; 965} 966 967static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, 968 int idx, u8 *dst, u8 *next_hop, 969 struct mpath_info *pinfo) 970{ 971 struct ieee80211_sub_if_data *sdata; 972 struct mesh_path *mpath; 973 974 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 975 976 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 977 return -ENOTSUPP; 978 979 rcu_read_lock(); 980 mpath = mesh_path_lookup_by_idx(idx, sdata); 981 if (!mpath) { 982 rcu_read_unlock(); 983 return -ENOENT; 984 } 985 memcpy(dst, mpath->dst, ETH_ALEN); 986 mpath_set_pinfo(mpath, next_hop, pinfo); 987 rcu_read_unlock(); 988 return 0; 989} 990 991static int ieee80211_get_mesh_params(struct wiphy *wiphy, 992 struct net_device *dev, 993 struct mesh_config *conf) 994{ 995 struct ieee80211_sub_if_data *sdata; 996 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 997 998 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 999 return -ENOTSUPP; 1000 memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config)); 1001 return 0; 1002} 1003 1004static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) 1005{ 1006 return (mask >> (parm-1)) & 0x1; 1007} 1008 1009static int ieee80211_set_mesh_params(struct wiphy *wiphy, 1010 struct net_device *dev, 1011 const struct mesh_config *nconf, u32 mask) 1012{ 1013 struct mesh_config *conf; 1014 struct ieee80211_sub_if_data *sdata; 1015 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1016 1017 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 1018 return -ENOTSUPP; 1019 1020 /* Set the config options which we are interested in setting */ 1021 conf = &(sdata->u.mesh.mshcfg); 1022 if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask)) 1023 conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout; 1024 if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask)) 1025 conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout; 1026 if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask)) 1027 conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout; 1028 if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask)) 1029 conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; 1030 if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask)) 1031 conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; 1032 if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) 1033 conf->dot11MeshTTL = nconf->dot11MeshTTL; 1034 if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) 1035 conf->auto_open_plinks = nconf->auto_open_plinks; 1036 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) 1037 conf->dot11MeshHWMPmaxPREQretries = 1038 nconf->dot11MeshHWMPmaxPREQretries; 1039 if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) 1040 conf->path_refresh_time = nconf->path_refresh_time; 1041 if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask)) 1042 conf->min_discovery_timeout = nconf->min_discovery_timeout; 1043 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask)) 1044 conf->dot11MeshHWMPactivePathTimeout = 1045 nconf->dot11MeshHWMPactivePathTimeout; 1046 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask)) 1047 conf->dot11MeshHWMPpreqMinInterval = 1048 nconf->dot11MeshHWMPpreqMinInterval; 1049 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, 1050 mask)) 1051 conf->dot11MeshHWMPnetDiameterTraversalTime = 1052 nconf->dot11MeshHWMPnetDiameterTraversalTime; 1053 return 0; 1054} 1055 1056#endif 1057 1058static int ieee80211_change_bss(struct wiphy *wiphy, 1059 struct net_device *dev, 1060 struct bss_parameters *params) 1061{ 1062 struct ieee80211_sub_if_data *sdata; 1063 u32 changed = 0; 1064 1065 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1066 1067 if (sdata->vif.type != NL80211_IFTYPE_AP) 1068 return -EINVAL; 1069 1070 if (params->use_cts_prot >= 0) { 1071 sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; 1072 changed |= BSS_CHANGED_ERP_CTS_PROT; 1073 } 1074 if (params->use_short_preamble >= 0) { 1075 sdata->vif.bss_conf.use_short_preamble = 1076 params->use_short_preamble; 1077 changed |= BSS_CHANGED_ERP_PREAMBLE; 1078 } 1079 if (params->use_short_slot_time >= 0) { 1080 sdata->vif.bss_conf.use_short_slot = 1081 params->use_short_slot_time; 1082 changed |= BSS_CHANGED_ERP_SLOT; 1083 } 1084 1085 if (params->basic_rates) { 1086 int i, j; 1087 u32 rates = 0; 1088 struct ieee80211_local *local = wiphy_priv(wiphy); 1089 struct ieee80211_supported_band *sband = 1090 wiphy->bands[local->oper_channel->band]; 1091 1092 for (i = 0; i < params->basic_rates_len; i++) { 1093 int rate = (params->basic_rates[i] & 0x7f) * 5; 1094 for (j = 0; j < sband->n_bitrates; j++) { 1095 if (sband->bitrates[j].bitrate == rate) 1096 rates |= BIT(j); 1097 } 1098 } 1099 sdata->vif.bss_conf.basic_rates = rates; 1100 changed |= BSS_CHANGED_BASIC_RATES; 1101 } 1102 1103 ieee80211_bss_info_change_notify(sdata, changed); 1104 1105 return 0; 1106} 1107 1108static int ieee80211_set_txq_params(struct wiphy *wiphy, 1109 struct ieee80211_txq_params *params) 1110{ 1111 struct ieee80211_local *local = wiphy_priv(wiphy); 1112 struct ieee80211_tx_queue_params p; 1113 1114 if (!local->ops->conf_tx) 1115 return -EOPNOTSUPP; 1116 1117 memset(&p, 0, sizeof(p)); 1118 p.aifs = params->aifs; 1119 p.cw_max = params->cwmax; 1120 p.cw_min = params->cwmin; 1121 p.txop = params->txop; 1122 if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) { 1123 printk(KERN_DEBUG "%s: failed to set TX queue " 1124 "parameters for queue %d\n", local->mdev->name, 1125 params->queue); 1126 return -EINVAL; 1127 } 1128 1129 return 0; 1130} 1131 1132static int ieee80211_set_channel(struct wiphy *wiphy, 1133 struct ieee80211_channel *chan, 1134 enum nl80211_channel_type channel_type) 1135{ 1136 struct ieee80211_local *local = wiphy_priv(wiphy); 1137 1138 local->oper_channel = chan; 1139 local->oper_channel_type = channel_type; 1140 1141 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1142} 1143 1144struct cfg80211_ops mac80211_config_ops = { 1145 .add_virtual_intf = ieee80211_add_iface, 1146 .del_virtual_intf = ieee80211_del_iface, 1147 .change_virtual_intf = ieee80211_change_iface, 1148 .add_key = ieee80211_add_key, 1149 .del_key = ieee80211_del_key, 1150 .get_key = ieee80211_get_key, 1151 .set_default_key = ieee80211_config_default_key, 1152 .add_beacon = ieee80211_add_beacon, 1153 .set_beacon = ieee80211_set_beacon, 1154 .del_beacon = ieee80211_del_beacon, 1155 .add_station = ieee80211_add_station, 1156 .del_station = ieee80211_del_station, 1157 .change_station = ieee80211_change_station, 1158 .get_station = ieee80211_get_station, 1159 .dump_station = ieee80211_dump_station, 1160#ifdef CONFIG_MAC80211_MESH 1161 .add_mpath = ieee80211_add_mpath, 1162 .del_mpath = ieee80211_del_mpath, 1163 .change_mpath = ieee80211_change_mpath, 1164 .get_mpath = ieee80211_get_mpath, 1165 .dump_mpath = ieee80211_dump_mpath, 1166 .set_mesh_params = ieee80211_set_mesh_params, 1167 .get_mesh_params = ieee80211_get_mesh_params, 1168#endif 1169 .change_bss = ieee80211_change_bss, 1170 .set_txq_params = ieee80211_set_txq_params, 1171 .set_channel = ieee80211_set_channel, 1172};