cfg.c
Go to the documentation of this file.
00001 /*
00002  * mac80211 configuration hooks for cfg80211
00003  *
00004  * Copyright 2006-2010  Johannes Berg <johannes@sipsolutions.net>
00005  *
00006  * This file is GPLv2 as found in COPYING.
00007  */
00008 
00009 #include <linux/ieee80211.h>
00010 #include <linux/nl80211.h>
00011 #include <linux/rtnetlink.h>
00012 #include <linux/slab.h>
00013 #include <net/net_namespace.h>
00014 #include <linux/rcupdate.h>
00015 #include <linux/if_ether.h>
00016 #include <net/cfg80211.h>
00017 #include "ieee80211_i.h"
00018 #include "driver-ops.h"
00019 #include "cfg.h"
00020 #include "rate.h"
00021 #include "mesh.h"
00022 
00023 static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name,
00024                                               enum nl80211_iftype type,
00025                                               u32 *flags,
00026                                               struct vif_params *params)
00027 {
00028         struct ieee80211_local *local = wiphy_priv(wiphy);
00029         struct net_device *dev;
00030         struct ieee80211_sub_if_data *sdata;
00031         int err;
00032 
00033         err = ieee80211_if_add(local, name, &dev, type, params);
00034         if (err)
00035                 return ERR_PTR(err);
00036 
00037         if (type == NL80211_IFTYPE_MONITOR && flags) {
00038                 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00039                 sdata->u.mntr_flags = *flags;
00040         }
00041 
00042         return dev;
00043 }
00044 
00045 static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev)
00046 {
00047         ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev));
00048 
00049         return 0;
00050 }
00051 
00052 static int ieee80211_change_iface(struct wiphy *wiphy,
00053                                   struct net_device *dev,
00054                                   enum nl80211_iftype type, u32 *flags,
00055                                   struct vif_params *params)
00056 {
00057         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00058         int ret;
00059 
00060         ret = ieee80211_if_change_type(sdata, type);
00061         if (ret)
00062                 return ret;
00063 
00064         if (type == NL80211_IFTYPE_AP_VLAN &&
00065             params && params->use_4addr == 0)
00066                 RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
00067         else if (type == NL80211_IFTYPE_STATION &&
00068                  params && params->use_4addr >= 0)
00069                 sdata->u.mgd.use_4addr = params->use_4addr;
00070 
00071         if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
00072                 struct ieee80211_local *local = sdata->local;
00073 
00074                 if (ieee80211_sdata_running(sdata)) {
00075                         /*
00076                          * Prohibit MONITOR_FLAG_COOK_FRAMES to be
00077                          * changed while the interface is up.
00078                          * Else we would need to add a lot of cruft
00079                          * to update everything:
00080                          *      cooked_mntrs, monitor and all fif_* counters
00081                          *      reconfigure hardware
00082                          */
00083                         if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
00084                             (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
00085                                 return -EBUSY;
00086 
00087                         ieee80211_adjust_monitor_flags(sdata, -1);
00088                         sdata->u.mntr_flags = *flags;
00089                         ieee80211_adjust_monitor_flags(sdata, 1);
00090 
00091                         ieee80211_configure_filter(local);
00092                 } else {
00093                         /*
00094                          * Because the interface is down, ieee80211_do_stop
00095                          * and ieee80211_do_open take care of "everything"
00096                          * mentioned in the comment above.
00097                          */
00098                         sdata->u.mntr_flags = *flags;
00099                 }
00100         }
00101 
00102         return 0;
00103 }
00104 
00105 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
00106                              u8 key_idx, bool pairwise, const u8 *mac_addr,
00107                              struct key_params *params)
00108 {
00109         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00110         struct sta_info *sta = NULL;
00111         struct ieee80211_key *key;
00112         int err;
00113 
00114         if (!ieee80211_sdata_running(sdata))
00115                 return -ENETDOWN;
00116 
00117         /* reject WEP and TKIP keys if WEP failed to initialize */
00118         switch (params->cipher) {
00119         case WLAN_CIPHER_SUITE_WEP40:
00120         case WLAN_CIPHER_SUITE_TKIP:
00121         case WLAN_CIPHER_SUITE_WEP104:
00122                 if (IS_ERR(sdata->local->wep_tx_tfm))
00123                         return -EINVAL;
00124                 break;
00125         default:
00126                 break;
00127         }
00128 
00129         key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len,
00130                                   params->key, params->seq_len, params->seq);
00131         if (IS_ERR(key))
00132                 return PTR_ERR(key);
00133 
00134         if (pairwise)
00135                 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
00136 
00137         mutex_lock(&sdata->local->sta_mtx);
00138 
00139         if (mac_addr) {
00140                 if (ieee80211_vif_is_mesh(&sdata->vif))
00141                         sta = sta_info_get(sdata, mac_addr);
00142                 else
00143                         sta = sta_info_get_bss(sdata, mac_addr);
00144                 if (!sta) {
00145                         ieee80211_key_free(sdata->local, key);
00146                         err = -ENOENT;
00147                         goto out_unlock;
00148                 }
00149         }
00150 
00151         err = ieee80211_key_link(key, sdata, sta);
00152         if (err)
00153                 ieee80211_key_free(sdata->local, key);
00154 
00155  out_unlock:
00156         mutex_unlock(&sdata->local->sta_mtx);
00157 
00158         return err;
00159 }
00160 
00161 static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
00162                              u8 key_idx, bool pairwise, const u8 *mac_addr)
00163 {
00164         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00165         struct ieee80211_local *local = sdata->local;
00166         struct sta_info *sta;
00167         struct ieee80211_key *key = NULL;
00168         int ret;
00169 
00170         mutex_lock(&local->sta_mtx);
00171         mutex_lock(&local->key_mtx);
00172 
00173         if (mac_addr) {
00174                 ret = -ENOENT;
00175 
00176                 sta = sta_info_get_bss(sdata, mac_addr);
00177                 if (!sta)
00178                         goto out_unlock;
00179 
00180                 if (pairwise)
00181                         key = key_mtx_dereference(local, sta->ptk);
00182                 else
00183                         key = key_mtx_dereference(local, sta->gtk[key_idx]);
00184         } else
00185                 key = key_mtx_dereference(local, sdata->keys[key_idx]);
00186 
00187         if (!key) {
00188                 ret = -ENOENT;
00189                 goto out_unlock;
00190         }
00191 
00192         __ieee80211_key_free(key);
00193 
00194         ret = 0;
00195  out_unlock:
00196         mutex_unlock(&local->key_mtx);
00197         mutex_unlock(&local->sta_mtx);
00198 
00199         return ret;
00200 }
00201 
00202 static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
00203                              u8 key_idx, bool pairwise, const u8 *mac_addr,
00204                              void *cookie,
00205                              void (*callback)(void *cookie,
00206                                               struct key_params *params))
00207 {
00208         struct ieee80211_sub_if_data *sdata;
00209         struct sta_info *sta = NULL;
00210         u8 seq[6] = {0};
00211         struct key_params params;
00212         struct ieee80211_key *key = NULL;
00213         u64 pn64;
00214         u32 iv32;
00215         u16 iv16;
00216         int err = -ENOENT;
00217 
00218         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00219 
00220         rcu_read_lock();
00221 
00222         if (mac_addr) {
00223                 sta = sta_info_get_bss(sdata, mac_addr);
00224                 if (!sta)
00225                         goto out;
00226 
00227                 if (pairwise)
00228                         key = rcu_dereference(sta->ptk);
00229                 else if (key_idx < NUM_DEFAULT_KEYS)
00230                         key = rcu_dereference(sta->gtk[key_idx]);
00231         } else
00232                 key = rcu_dereference(sdata->keys[key_idx]);
00233 
00234         if (!key)
00235                 goto out;
00236 
00237         memset(&params, 0, sizeof(params));
00238 
00239         params.cipher = key->conf.cipher;
00240 
00241         switch (key->conf.cipher) {
00242         case WLAN_CIPHER_SUITE_TKIP:
00243                 iv32 = key->u.tkip.tx.iv32;
00244                 iv16 = key->u.tkip.tx.iv16;
00245 
00246                 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
00247                         drv_get_tkip_seq(sdata->local,
00248                                          key->conf.hw_key_idx,
00249                                          &iv32, &iv16);
00250 
00251                 seq[0] = iv16 & 0xff;
00252                 seq[1] = (iv16 >> 8) & 0xff;
00253                 seq[2] = iv32 & 0xff;
00254                 seq[3] = (iv32 >> 8) & 0xff;
00255                 seq[4] = (iv32 >> 16) & 0xff;
00256                 seq[5] = (iv32 >> 24) & 0xff;
00257                 params.seq = seq;
00258                 params.seq_len = 6;
00259                 break;
00260         case WLAN_CIPHER_SUITE_CCMP:
00261                 pn64 = atomic64_read(&key->u.ccmp.tx_pn);
00262                 seq[0] = pn64;
00263                 seq[1] = pn64 >> 8;
00264                 seq[2] = pn64 >> 16;
00265                 seq[3] = pn64 >> 24;
00266                 seq[4] = pn64 >> 32;
00267                 seq[5] = pn64 >> 40;
00268                 params.seq = seq;
00269                 params.seq_len = 6;
00270                 break;
00271         case WLAN_CIPHER_SUITE_AES_CMAC:
00272                 pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
00273                 seq[0] = pn64;
00274                 seq[1] = pn64 >> 8;
00275                 seq[2] = pn64 >> 16;
00276                 seq[3] = pn64 >> 24;
00277                 seq[4] = pn64 >> 32;
00278                 seq[5] = pn64 >> 40;
00279                 params.seq = seq;
00280                 params.seq_len = 6;
00281                 break;
00282         }
00283 
00284         params.key = key->conf.key;
00285         params.key_len = key->conf.keylen;
00286 
00287         callback(cookie, &params);
00288         err = 0;
00289 
00290  out:
00291         rcu_read_unlock();
00292         return err;
00293 }
00294 
00295 static int ieee80211_config_default_key(struct wiphy *wiphy,
00296                                         struct net_device *dev,
00297                                         u8 key_idx, bool uni,
00298                                         bool multi)
00299 {
00300         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00301 
00302         ieee80211_set_default_key(sdata, key_idx, uni, multi);
00303 
00304         return 0;
00305 }
00306 
00307 static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
00308                                              struct net_device *dev,
00309                                              u8 key_idx)
00310 {
00311         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00312 
00313         ieee80211_set_default_mgmt_key(sdata, key_idx);
00314 
00315         return 0;
00316 }
00317 
00318 static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
00319 {
00320         if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
00321                 struct ieee80211_supported_band *sband;
00322                 sband = sta->local->hw.wiphy->bands[
00323                                 sta->local->hw.conf.channel->band];
00324                 rate->legacy = sband->bitrates[idx].bitrate;
00325         } else
00326                 rate->mcs = idx;
00327 }
00328 
00329 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
00330 {
00331         struct ieee80211_sub_if_data *sdata = sta->sdata;
00332         struct timespec uptime;
00333 
00334         sinfo->generation = sdata->local->sta_generation;
00335 
00336         sinfo->filled = STATION_INFO_INACTIVE_TIME |
00337                         STATION_INFO_RX_BYTES |
00338                         STATION_INFO_TX_BYTES |
00339                         STATION_INFO_RX_PACKETS |
00340                         STATION_INFO_TX_PACKETS |
00341                         STATION_INFO_TX_RETRIES |
00342                         STATION_INFO_TX_FAILED |
00343                         STATION_INFO_TX_BITRATE |
00344                         STATION_INFO_RX_BITRATE |
00345                         STATION_INFO_RX_DROP_MISC |
00346                         STATION_INFO_BSS_PARAM |
00347                         STATION_INFO_CONNECTED_TIME |
00348                         STATION_INFO_STA_FLAGS;
00349 
00350         do_posix_clock_monotonic_gettime(&uptime);
00351         sinfo->connected_time = uptime.tv_sec - sta->last_connected;
00352 
00353         sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
00354         sinfo->rx_bytes = sta->rx_bytes;
00355         sinfo->tx_bytes = sta->tx_bytes;
00356         sinfo->rx_packets = sta->rx_packets;
00357         sinfo->tx_packets = sta->tx_packets;
00358         sinfo->tx_retries = sta->tx_retry_count;
00359         sinfo->tx_failed = sta->tx_retry_failed;
00360         sinfo->rx_dropped_misc = sta->rx_dropped;
00361 
00362         if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
00363             (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
00364                 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
00365                 sinfo->signal = (s8)sta->last_signal;
00366                 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
00367         }
00368 
00369         sinfo->txrate.flags = 0;
00370         if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
00371                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
00372         if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
00373                 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
00374         if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
00375                 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
00376         rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx);
00377 
00378         sinfo->rxrate.flags = 0;
00379         if (sta->last_rx_rate_flag & RX_FLAG_HT)
00380                 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
00381         if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
00382                 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
00383         if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
00384                 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
00385         rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx);
00386 
00387         if (ieee80211_vif_is_mesh(&sdata->vif)) {
00388 #ifdef CONFIG_MAC80211_MESH
00389                 sinfo->filled |= STATION_INFO_LLID |
00390                                  STATION_INFO_PLID |
00391                                  STATION_INFO_PLINK_STATE;
00392 
00393                 sinfo->llid = le16_to_cpu(sta->llid);
00394                 sinfo->plid = le16_to_cpu(sta->plid);
00395                 sinfo->plink_state = sta->plink_state;
00396 #endif
00397         }
00398 
00399         sinfo->bss_param.flags = 0;
00400         if (sdata->vif.bss_conf.use_cts_prot)
00401                 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
00402         if (sdata->vif.bss_conf.use_short_preamble)
00403                 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
00404         if (sdata->vif.bss_conf.use_short_slot)
00405                 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
00406         sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
00407         sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
00408 
00409         sinfo->sta_flags.set = 0;
00410         sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
00411                                 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
00412                                 BIT(NL80211_STA_FLAG_WME) |
00413                                 BIT(NL80211_STA_FLAG_MFP) |
00414                                 BIT(NL80211_STA_FLAG_AUTHENTICATED);
00415         if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
00416                 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
00417         if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
00418                 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
00419         if (test_sta_flag(sta, WLAN_STA_WME))
00420                 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
00421         if (test_sta_flag(sta, WLAN_STA_MFP))
00422                 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
00423         if (test_sta_flag(sta, WLAN_STA_AUTH))
00424                 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
00425 }
00426 
00427 
00428 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
00429                                  int idx, u8 *mac, struct station_info *sinfo)
00430 {
00431         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00432         struct sta_info *sta;
00433         int ret = -ENOENT;
00434 
00435         rcu_read_lock();
00436 
00437         sta = sta_info_get_by_idx(sdata, idx);
00438         if (sta) {
00439                 ret = 0;
00440                 memcpy(mac, sta->sta.addr, ETH_ALEN);
00441                 sta_set_sinfo(sta, sinfo);
00442         }
00443 
00444         rcu_read_unlock();
00445 
00446         return ret;
00447 }
00448 
00449 static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
00450                                  int idx, struct survey_info *survey)
00451 {
00452         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
00453 
00454         return drv_get_survey(local, idx, survey);
00455 }
00456 
00457 static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
00458                                  u8 *mac, struct station_info *sinfo)
00459 {
00460         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00461         struct sta_info *sta;
00462         int ret = -ENOENT;
00463 
00464         rcu_read_lock();
00465 
00466         sta = sta_info_get_bss(sdata, mac);
00467         if (sta) {
00468                 ret = 0;
00469                 sta_set_sinfo(sta, sinfo);
00470         }
00471 
00472         rcu_read_unlock();
00473 
00474         return ret;
00475 }
00476 
00477 static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata,
00478                                      struct beacon_parameters *params)
00479 {
00480         struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
00481 
00482         bss_conf->ssid_len = params->ssid_len;
00483 
00484         if (params->ssid_len)
00485                 memcpy(bss_conf->ssid, params->ssid, params->ssid_len);
00486 
00487         bss_conf->hidden_ssid =
00488                 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
00489 }
00490 
00491 /*
00492  * This handles both adding a beacon and setting new beacon info
00493  */
00494 static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
00495                                    struct beacon_parameters *params)
00496 {
00497         struct beacon_data *new, *old;
00498         int new_head_len, new_tail_len;
00499         int size;
00500         int err = -EINVAL;
00501 
00502         old = rtnl_dereference(sdata->u.ap.beacon);
00503 
00504         /* head must not be zero-length */
00505         if (params->head && !params->head_len)
00506                 return -EINVAL;
00507 
00508         /*
00509          * This is a kludge. beacon interval should really be part
00510          * of the beacon information.
00511          */
00512         if (params->interval &&
00513             (sdata->vif.bss_conf.beacon_int != params->interval)) {
00514                 sdata->vif.bss_conf.beacon_int = params->interval;
00515                 ieee80211_bss_info_change_notify(sdata,
00516                                                  BSS_CHANGED_BEACON_INT);
00517         }
00518 
00519         /* Need to have a beacon head if we don't have one yet */
00520         if (!params->head && !old)
00521                 return err;
00522 
00523         /* sorry, no way to start beaconing without dtim period */
00524         if (!params->dtim_period && !old)
00525                 return err;
00526 
00527         /* new or old head? */
00528         if (params->head)
00529                 new_head_len = params->head_len;
00530         else
00531                 new_head_len = old->head_len;
00532 
00533         /* new or old tail? */
00534         if (params->tail || !old)
00535                 /* params->tail_len will be zero for !params->tail */
00536                 new_tail_len = params->tail_len;
00537         else
00538                 new_tail_len = old->tail_len;
00539 
00540         size = sizeof(*new) + new_head_len + new_tail_len;
00541 
00542         new = kzalloc(size, GFP_KERNEL);
00543         if (!new)
00544                 return -ENOMEM;
00545 
00546         /* start filling the new info now */
00547 
00548         /* new or old dtim period? */
00549         if (params->dtim_period)
00550                 new->dtim_period = params->dtim_period;
00551         else
00552                 new->dtim_period = old->dtim_period;
00553 
00554         /*
00555          * pointers go into the block we allocated,
00556          * memory is | beacon_data | head | tail |
00557          */
00558         new->head = ((u8 *) new) + sizeof(*new);
00559         new->tail = new->head + new_head_len;
00560         new->head_len = new_head_len;
00561         new->tail_len = new_tail_len;
00562 
00563         /* copy in head */
00564         if (params->head)
00565                 memcpy(new->head, params->head, new_head_len);
00566         else
00567                 memcpy(new->head, old->head, new_head_len);
00568 
00569         /* copy in optional tail */
00570         if (params->tail)
00571                 memcpy(new->tail, params->tail, new_tail_len);
00572         else
00573                 if (old)
00574                         memcpy(new->tail, old->tail, new_tail_len);
00575 
00576         sdata->vif.bss_conf.dtim_period = new->dtim_period;
00577 
00578         rcu_assign_pointer(sdata->u.ap.beacon, new);
00579 
00580         synchronize_rcu();
00581 
00582         kfree(old);
00583 
00584         ieee80211_config_ap_ssid(sdata, params);
00585 
00586         ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
00587                                                 BSS_CHANGED_BEACON |
00588                                                 BSS_CHANGED_SSID);
00589         return 0;
00590 }
00591 
00592 static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
00593                                 struct beacon_parameters *params)
00594 {
00595         struct ieee80211_sub_if_data *sdata;
00596         struct beacon_data *old;
00597 
00598         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00599 
00600         old = rtnl_dereference(sdata->u.ap.beacon);
00601         if (old)
00602                 return -EALREADY;
00603 
00604         return ieee80211_config_beacon(sdata, params);
00605 }
00606 
00607 static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
00608                                 struct beacon_parameters *params)
00609 {
00610         struct ieee80211_sub_if_data *sdata;
00611         struct beacon_data *old;
00612 
00613         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00614 
00615         old = rtnl_dereference(sdata->u.ap.beacon);
00616         if (!old)
00617                 return -ENOENT;
00618 
00619         return ieee80211_config_beacon(sdata, params);
00620 }
00621 
00622 static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
00623 {
00624         struct ieee80211_sub_if_data *sdata;
00625         struct beacon_data *old;
00626 
00627         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00628 
00629         old = rtnl_dereference(sdata->u.ap.beacon);
00630         if (!old)
00631                 return -ENOENT;
00632 
00633         RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
00634         synchronize_rcu();
00635         kfree(old);
00636 
00637         ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
00638         return 0;
00639 }
00640 
00641 /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
00642 struct iapp_layer2_update {
00643         u8 da[ETH_ALEN];        /* broadcast */
00644         u8 sa[ETH_ALEN];        /* STA addr */
00645         __be16 len;             /* 6 */
00646         u8 dsap;                /* 0 */
00647         u8 ssap;                /* 0 */
00648         u8 control;
00649         u8 xid_info[3];
00650 } __packed;
00651 
00652 static void ieee80211_send_layer2_update(struct sta_info *sta)
00653 {
00654         struct iapp_layer2_update *msg;
00655         struct sk_buff *skb;
00656 
00657         /* Send Level 2 Update Frame to update forwarding tables in layer 2
00658          * bridge devices */
00659 
00660         skb = dev_alloc_skb(sizeof(*msg));
00661         if (!skb)
00662                 return;
00663         msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
00664 
00665         /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
00666          * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
00667 
00668         memset(msg->da, 0xff, ETH_ALEN);
00669         memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
00670         msg->len = htons(6);
00671         msg->dsap = 0;
00672         msg->ssap = 0x01;       /* NULL LSAP, CR Bit: Response */
00673         msg->control = 0xaf;    /* XID response lsb.1111F101.
00674                                  * F=0 (no poll command; unsolicited frame) */
00675         msg->xid_info[0] = 0x81;        /* XID format identifier */
00676         msg->xid_info[1] = 1;   /* LLC types/classes: Type 1 LLC */
00677         msg->xid_info[2] = 0;   /* XID sender's receive window size (RW) */
00678 
00679         skb->dev = sta->sdata->dev;
00680         skb->protocol = eth_type_trans(skb, sta->sdata->dev);
00681         memset(skb->cb, 0, sizeof(skb->cb));
00682         netif_rx_ni(skb);
00683 }
00684 
00685 static void sta_apply_parameters(struct ieee80211_local *local,
00686                                  struct sta_info *sta,
00687                                  struct station_parameters *params)
00688 {
00689         u32 rates;
00690         int i, j;
00691         struct ieee80211_supported_band *sband;
00692         struct ieee80211_sub_if_data *sdata = sta->sdata;
00693         u32 mask, set;
00694 
00695         sband = local->hw.wiphy->bands[local->oper_channel->band];
00696 
00697         mask = params->sta_flags_mask;
00698         set = params->sta_flags_set;
00699 
00700         if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
00701                 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
00702                         set_sta_flag(sta, WLAN_STA_AUTHORIZED);
00703                 else
00704                         clear_sta_flag(sta, WLAN_STA_AUTHORIZED);
00705         }
00706 
00707         if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
00708                 if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
00709                         set_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
00710                 else
00711                         clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
00712         }
00713 
00714         if (mask & BIT(NL80211_STA_FLAG_WME)) {
00715                 if (set & BIT(NL80211_STA_FLAG_WME)) {
00716                         set_sta_flag(sta, WLAN_STA_WME);
00717                         sta->sta.wme = true;
00718                 } else {
00719                         clear_sta_flag(sta, WLAN_STA_WME);
00720                         sta->sta.wme = false;
00721                 }
00722         }
00723 
00724         if (mask & BIT(NL80211_STA_FLAG_MFP)) {
00725                 if (set & BIT(NL80211_STA_FLAG_MFP))
00726                         set_sta_flag(sta, WLAN_STA_MFP);
00727                 else
00728                         clear_sta_flag(sta, WLAN_STA_MFP);
00729         }
00730 
00731         if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
00732                 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
00733                         set_sta_flag(sta, WLAN_STA_AUTH);
00734                 else
00735                         clear_sta_flag(sta, WLAN_STA_AUTH);
00736         }
00737 
00738         if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
00739                 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER))
00740                         set_sta_flag(sta, WLAN_STA_TDLS_PEER);
00741                 else
00742                         clear_sta_flag(sta, WLAN_STA_TDLS_PEER);
00743         }
00744 
00745         if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) {
00746                 sta->sta.uapsd_queues = params->uapsd_queues;
00747                 sta->sta.max_sp = params->max_sp;
00748         }
00749 
00750         /*
00751          * cfg80211 validates this (1-2007) and allows setting the AID
00752          * only when creating a new station entry
00753          */
00754         if (params->aid)
00755                 sta->sta.aid = params->aid;
00756 
00757         /*
00758          * FIXME: updating the following information is racy when this
00759          *        function is called from ieee80211_change_station().
00760          *        However, all this information should be static so
00761          *        maybe we should just reject attemps to change it.
00762          */
00763 
00764         if (params->listen_interval >= 0)
00765                 sta->listen_interval = params->listen_interval;
00766 
00767         if (params->supported_rates) {
00768                 rates = 0;
00769 
00770                 for (i = 0; i < params->supported_rates_len; i++) {
00771                         int rate = (params->supported_rates[i] & 0x7f) * 5;
00772                         for (j = 0; j < sband->n_bitrates; j++) {
00773                                 if (sband->bitrates[j].bitrate == rate)
00774                                         rates |= BIT(j);
00775                         }
00776                 }
00777                 sta->sta.supp_rates[local->oper_channel->band] = rates;
00778         }
00779 
00780         if (params->ht_capa)
00781                 ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
00782                                                   params->ht_capa,
00783                                                   &sta->sta.ht_cap);
00784 
00785         if (ieee80211_vif_is_mesh(&sdata->vif)) {
00786 #ifdef CONFIG_MAC80211_MESH
00787                 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED)
00788                         switch (params->plink_state) {
00789                         case NL80211_PLINK_LISTEN:
00790                         case NL80211_PLINK_ESTAB:
00791                         case NL80211_PLINK_BLOCKED:
00792                                 sta->plink_state = params->plink_state;
00793                                 break;
00794                         default:
00795                                 /*  nothing  */
00796                                 break;
00797                         }
00798                 else
00799                         switch (params->plink_action) {
00800                         case PLINK_ACTION_OPEN:
00801                                 mesh_plink_open(sta);
00802                                 break;
00803                         case PLINK_ACTION_BLOCK:
00804                                 mesh_plink_block(sta);
00805                                 break;
00806                         }
00807 #endif
00808         }
00809 }
00810 
00811 static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
00812                                  u8 *mac, struct station_parameters *params)
00813 {
00814         struct ieee80211_local *local = wiphy_priv(wiphy);
00815         struct sta_info *sta;
00816         struct ieee80211_sub_if_data *sdata;
00817         int err;
00818         int layer2_update;
00819 
00820         if (params->vlan) {
00821                 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
00822 
00823                 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
00824                     sdata->vif.type != NL80211_IFTYPE_AP)
00825                         return -EINVAL;
00826         } else
00827                 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00828 
00829         if (compare_ether_addr(mac, sdata->vif.addr) == 0)
00830                 return -EINVAL;
00831 
00832         if (is_multicast_ether_addr(mac))
00833                 return -EINVAL;
00834 
00835         /* Only TDLS-supporting stations can add TDLS peers */
00836         if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
00837             !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
00838               sdata->vif.type == NL80211_IFTYPE_STATION))
00839                 return -ENOTSUPP;
00840 
00841         sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
00842         if (!sta)
00843                 return -ENOMEM;
00844 
00845         set_sta_flag(sta, WLAN_STA_AUTH);
00846         set_sta_flag(sta, WLAN_STA_ASSOC);
00847 
00848         sta_apply_parameters(local, sta, params);
00849 
00850         rate_control_rate_init(sta);
00851 
00852         layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
00853                 sdata->vif.type == NL80211_IFTYPE_AP;
00854 
00855         err = sta_info_insert_rcu(sta);
00856         if (err) {
00857                 rcu_read_unlock();
00858                 return err;
00859         }
00860 
00861         if (layer2_update)
00862                 ieee80211_send_layer2_update(sta);
00863 
00864         rcu_read_unlock();
00865 
00866         return 0;
00867 }
00868 
00869 static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
00870                                  u8 *mac)
00871 {
00872         struct ieee80211_local *local = wiphy_priv(wiphy);
00873         struct ieee80211_sub_if_data *sdata;
00874 
00875         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00876 
00877         if (mac)
00878                 return sta_info_destroy_addr_bss(sdata, mac);
00879 
00880         sta_info_flush(local, sdata);
00881         return 0;
00882 }
00883 
00884 static int ieee80211_change_station(struct wiphy *wiphy,
00885                                     struct net_device *dev,
00886                                     u8 *mac,
00887                                     struct station_parameters *params)
00888 {
00889         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00890         struct ieee80211_local *local = wiphy_priv(wiphy);
00891         struct sta_info *sta;
00892         struct ieee80211_sub_if_data *vlansdata;
00893 
00894         rcu_read_lock();
00895 
00896         sta = sta_info_get_bss(sdata, mac);
00897         if (!sta) {
00898                 rcu_read_unlock();
00899                 return -ENOENT;
00900         }
00901 
00902         /* The TDLS bit cannot be toggled after the STA was added */
00903         if ((params->sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
00904             !!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) !=
00905             !!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
00906                 rcu_read_unlock();
00907                 return -EINVAL;
00908         }
00909 
00910         if (params->vlan && params->vlan != sta->sdata->dev) {
00911                 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
00912 
00913                 if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
00914                     vlansdata->vif.type != NL80211_IFTYPE_AP) {
00915                         rcu_read_unlock();
00916                         return -EINVAL;
00917                 }
00918 
00919                 if (params->vlan->ieee80211_ptr->use_4addr) {
00920                         if (vlansdata->u.vlan.sta) {
00921                                 rcu_read_unlock();
00922                                 return -EBUSY;
00923                         }
00924 
00925                         rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
00926                 }
00927 
00928                 sta->sdata = vlansdata;
00929                 ieee80211_send_layer2_update(sta);
00930         }
00931 
00932         sta_apply_parameters(local, sta, params);
00933 
00934         rcu_read_unlock();
00935 
00936         if (sdata->vif.type == NL80211_IFTYPE_STATION &&
00937             params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))
00938                 ieee80211_recalc_ps(local, -1);
00939 
00940         return 0;
00941 }
00942 
00943 #ifdef CONFIG_MAC80211_MESH
00944 static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
00945                                  u8 *dst, u8 *next_hop)
00946 {
00947         struct ieee80211_sub_if_data *sdata;
00948         struct mesh_path *mpath;
00949         struct sta_info *sta;
00950         int err;
00951 
00952         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00953 
00954         rcu_read_lock();
00955         sta = sta_info_get(sdata, next_hop);
00956         if (!sta) {
00957                 rcu_read_unlock();
00958                 return -ENOENT;
00959         }
00960 
00961         err = mesh_path_add(dst, sdata);
00962         if (err) {
00963                 rcu_read_unlock();
00964                 return err;
00965         }
00966 
00967         mpath = mesh_path_lookup(dst, sdata);
00968         if (!mpath) {
00969                 rcu_read_unlock();
00970                 return -ENXIO;
00971         }
00972         mesh_path_fix_nexthop(mpath, sta);
00973 
00974         rcu_read_unlock();
00975         return 0;
00976 }
00977 
00978 static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
00979                                  u8 *dst)
00980 {
00981         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00982 
00983         if (dst)
00984                 return mesh_path_del(dst, sdata);
00985 
00986         mesh_path_flush_by_iface(sdata);
00987         return 0;
00988 }
00989 
00990 static int ieee80211_change_mpath(struct wiphy *wiphy,
00991                                     struct net_device *dev,
00992                                     u8 *dst, u8 *next_hop)
00993 {
00994         struct ieee80211_sub_if_data *sdata;
00995         struct mesh_path *mpath;
00996         struct sta_info *sta;
00997 
00998         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
00999 
01000         rcu_read_lock();
01001 
01002         sta = sta_info_get(sdata, next_hop);
01003         if (!sta) {
01004                 rcu_read_unlock();
01005                 return -ENOENT;
01006         }
01007 
01008         mpath = mesh_path_lookup(dst, sdata);
01009         if (!mpath) {
01010                 rcu_read_unlock();
01011                 return -ENOENT;
01012         }
01013 
01014         mesh_path_fix_nexthop(mpath, sta);
01015 
01016         rcu_read_unlock();
01017         return 0;
01018 }
01019 
01020 static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
01021                             struct mpath_info *pinfo)
01022 {
01023         struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop);
01024 
01025         if (next_hop_sta)
01026                 memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN);
01027         else
01028                 memset(next_hop, 0, ETH_ALEN);
01029 
01030         pinfo->generation = mesh_paths_generation;
01031 
01032         pinfo->filled = MPATH_INFO_FRAME_QLEN |
01033                         MPATH_INFO_SN |
01034                         MPATH_INFO_METRIC |
01035                         MPATH_INFO_EXPTIME |
01036                         MPATH_INFO_DISCOVERY_TIMEOUT |
01037                         MPATH_INFO_DISCOVERY_RETRIES |
01038                         MPATH_INFO_FLAGS;
01039 
01040         pinfo->frame_qlen = mpath->frame_queue.qlen;
01041         pinfo->sn = mpath->sn;
01042         pinfo->metric = mpath->metric;
01043         if (time_before(jiffies, mpath->exp_time))
01044                 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
01045         pinfo->discovery_timeout =
01046                         jiffies_to_msecs(mpath->discovery_timeout);
01047         pinfo->discovery_retries = mpath->discovery_retries;
01048         pinfo->flags = 0;
01049         if (mpath->flags & MESH_PATH_ACTIVE)
01050                 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
01051         if (mpath->flags & MESH_PATH_RESOLVING)
01052                 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
01053         if (mpath->flags & MESH_PATH_SN_VALID)
01054                 pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
01055         if (mpath->flags & MESH_PATH_FIXED)
01056                 pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
01057         if (mpath->flags & MESH_PATH_RESOLVING)
01058                 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
01059 
01060         pinfo->flags = mpath->flags;
01061 }
01062 
01063 static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
01064                                u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
01065 
01066 {
01067         struct ieee80211_sub_if_data *sdata;
01068         struct mesh_path *mpath;
01069 
01070         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01071 
01072         rcu_read_lock();
01073         mpath = mesh_path_lookup(dst, sdata);
01074         if (!mpath) {
01075                 rcu_read_unlock();
01076                 return -ENOENT;
01077         }
01078         memcpy(dst, mpath->dst, ETH_ALEN);
01079         mpath_set_pinfo(mpath, next_hop, pinfo);
01080         rcu_read_unlock();
01081         return 0;
01082 }
01083 
01084 static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
01085                                  int idx, u8 *dst, u8 *next_hop,
01086                                  struct mpath_info *pinfo)
01087 {
01088         struct ieee80211_sub_if_data *sdata;
01089         struct mesh_path *mpath;
01090 
01091         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01092 
01093         rcu_read_lock();
01094         mpath = mesh_path_lookup_by_idx(idx, sdata);
01095         if (!mpath) {
01096                 rcu_read_unlock();
01097                 return -ENOENT;
01098         }
01099         memcpy(dst, mpath->dst, ETH_ALEN);
01100         mpath_set_pinfo(mpath, next_hop, pinfo);
01101         rcu_read_unlock();
01102         return 0;
01103 }
01104 
01105 static int ieee80211_get_mesh_config(struct wiphy *wiphy,
01106                                 struct net_device *dev,
01107                                 struct mesh_config *conf)
01108 {
01109         struct ieee80211_sub_if_data *sdata;
01110         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01111 
01112         memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
01113         return 0;
01114 }
01115 
01116 static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
01117 {
01118         return (mask >> (parm-1)) & 0x1;
01119 }
01120 
01121 static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
01122                 const struct mesh_setup *setup)
01123 {
01124         u8 *new_ie;
01125         const u8 *old_ie;
01126 
01127         /* allocate information elements */
01128         new_ie = NULL;
01129         old_ie = ifmsh->ie;
01130 
01131         if (setup->ie_len) {
01132                 new_ie = kmemdup(setup->ie, setup->ie_len,
01133                                 GFP_KERNEL);
01134                 if (!new_ie)
01135                         return -ENOMEM;
01136         }
01137         ifmsh->ie_len = setup->ie_len;
01138         ifmsh->ie = new_ie;
01139         kfree(old_ie);
01140 
01141         /* now copy the rest of the setup parameters */
01142         ifmsh->mesh_id_len = setup->mesh_id_len;
01143         memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
01144         ifmsh->mesh_pp_id = setup->path_sel_proto;
01145         ifmsh->mesh_pm_id = setup->path_metric;
01146         ifmsh->security = IEEE80211_MESH_SEC_NONE;
01147         if (setup->is_authenticated)
01148                 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
01149         if (setup->is_secure)
01150                 ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
01151 
01152         return 0;
01153 }
01154 
01155 static int ieee80211_update_mesh_config(struct wiphy *wiphy,
01156                                         struct net_device *dev, u32 mask,
01157                                         const struct mesh_config *nconf)
01158 {
01159         struct mesh_config *conf;
01160         struct ieee80211_sub_if_data *sdata;
01161         struct ieee80211_if_mesh *ifmsh;
01162 
01163         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01164         ifmsh = &sdata->u.mesh;
01165 
01166         /* Set the config options which we are interested in setting */
01167         conf = &(sdata->u.mesh.mshcfg);
01168         if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
01169                 conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout;
01170         if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask))
01171                 conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout;
01172         if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask))
01173                 conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout;
01174         if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask))
01175                 conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks;
01176         if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask))
01177                 conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
01178         if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
01179                 conf->dot11MeshTTL = nconf->dot11MeshTTL;
01180         if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
01181                 conf->dot11MeshTTL = nconf->element_ttl;
01182         if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
01183                 conf->auto_open_plinks = nconf->auto_open_plinks;
01184         if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
01185                 conf->dot11MeshHWMPmaxPREQretries =
01186                         nconf->dot11MeshHWMPmaxPREQretries;
01187         if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
01188                 conf->path_refresh_time = nconf->path_refresh_time;
01189         if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
01190                 conf->min_discovery_timeout = nconf->min_discovery_timeout;
01191         if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
01192                 conf->dot11MeshHWMPactivePathTimeout =
01193                         nconf->dot11MeshHWMPactivePathTimeout;
01194         if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
01195                 conf->dot11MeshHWMPpreqMinInterval =
01196                         nconf->dot11MeshHWMPpreqMinInterval;
01197         if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
01198                            mask))
01199                 conf->dot11MeshHWMPnetDiameterTraversalTime =
01200                         nconf->dot11MeshHWMPnetDiameterTraversalTime;
01201         if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) {
01202                 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
01203                 ieee80211_mesh_root_setup(ifmsh);
01204         }
01205         if (_chg_mesh_attr(NL80211_MESHCONF_GATE_ANNOUNCEMENTS, mask)) {
01206                 /* our current gate announcement implementation rides on root
01207                  * announcements, so require this ifmsh to also be a root node
01208                  * */
01209                 if (nconf->dot11MeshGateAnnouncementProtocol &&
01210                     !conf->dot11MeshHWMPRootMode) {
01211                         conf->dot11MeshHWMPRootMode = 1;
01212                         ieee80211_mesh_root_setup(ifmsh);
01213                 }
01214                 conf->dot11MeshGateAnnouncementProtocol =
01215                         nconf->dot11MeshGateAnnouncementProtocol;
01216         }
01217         if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) {
01218                 conf->dot11MeshHWMPRannInterval =
01219                         nconf->dot11MeshHWMPRannInterval;
01220         }
01221         return 0;
01222 }
01223 
01224 static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
01225                                const struct mesh_config *conf,
01226                                const struct mesh_setup *setup)
01227 {
01228         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01229         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
01230         int err;
01231 
01232         memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
01233         err = copy_mesh_setup(ifmsh, setup);
01234         if (err)
01235                 return err;
01236         ieee80211_start_mesh(sdata);
01237 
01238         return 0;
01239 }
01240 
01241 static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
01242 {
01243         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01244 
01245         ieee80211_stop_mesh(sdata);
01246 
01247         return 0;
01248 }
01249 #endif
01250 
01251 static int ieee80211_change_bss(struct wiphy *wiphy,
01252                                 struct net_device *dev,
01253                                 struct bss_parameters *params)
01254 {
01255         struct ieee80211_sub_if_data *sdata;
01256         u32 changed = 0;
01257 
01258         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01259 
01260         if (params->use_cts_prot >= 0) {
01261                 sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
01262                 changed |= BSS_CHANGED_ERP_CTS_PROT;
01263         }
01264         if (params->use_short_preamble >= 0) {
01265                 sdata->vif.bss_conf.use_short_preamble =
01266                         params->use_short_preamble;
01267                 changed |= BSS_CHANGED_ERP_PREAMBLE;
01268         }
01269 
01270         if (!sdata->vif.bss_conf.use_short_slot &&
01271             sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
01272                 sdata->vif.bss_conf.use_short_slot = true;
01273                 changed |= BSS_CHANGED_ERP_SLOT;
01274         }
01275 
01276         if (params->use_short_slot_time >= 0) {
01277                 sdata->vif.bss_conf.use_short_slot =
01278                         params->use_short_slot_time;
01279                 changed |= BSS_CHANGED_ERP_SLOT;
01280         }
01281 
01282         if (params->basic_rates) {
01283                 int i, j;
01284                 u32 rates = 0;
01285                 struct ieee80211_local *local = wiphy_priv(wiphy);
01286                 struct ieee80211_supported_band *sband =
01287                         wiphy->bands[local->oper_channel->band];
01288 
01289                 for (i = 0; i < params->basic_rates_len; i++) {
01290                         int rate = (params->basic_rates[i] & 0x7f) * 5;
01291                         for (j = 0; j < sband->n_bitrates; j++) {
01292                                 if (sband->bitrates[j].bitrate == rate)
01293                                         rates |= BIT(j);
01294                         }
01295                 }
01296                 sdata->vif.bss_conf.basic_rates = rates;
01297                 changed |= BSS_CHANGED_BASIC_RATES;
01298         }
01299 
01300         if (params->ap_isolate >= 0) {
01301                 if (params->ap_isolate)
01302                         sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
01303                 else
01304                         sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
01305         }
01306 
01307         if (params->ht_opmode >= 0) {
01308                 sdata->vif.bss_conf.ht_operation_mode =
01309                         (u16) params->ht_opmode;
01310                 changed |= BSS_CHANGED_HT;
01311         }
01312 
01313         ieee80211_bss_info_change_notify(sdata, changed);
01314 
01315         return 0;
01316 }
01317 
01318 static int ieee80211_set_txq_params(struct wiphy *wiphy,
01319                                     struct net_device *dev,
01320                                     struct ieee80211_txq_params *params)
01321 {
01322         struct ieee80211_local *local = wiphy_priv(wiphy);
01323         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01324         struct ieee80211_tx_queue_params p;
01325 
01326         if (!local->ops->conf_tx)
01327                 return -EOPNOTSUPP;
01328 
01329         memset(&p, 0, sizeof(p));
01330         p.aifs = params->aifs;
01331         p.cw_max = params->cwmax;
01332         p.cw_min = params->cwmin;
01333         p.txop = params->txop;
01334 
01335         /*
01336          * Setting tx queue params disables u-apsd because it's only
01337          * called in master mode.
01338          */
01339         p.uapsd = false;
01340 
01341         if (params->queue >= local->hw.queues)
01342                 return -EINVAL;
01343 
01344         sdata->tx_conf[params->queue] = p;
01345         if (drv_conf_tx(local, sdata, params->queue, &p)) {
01346                 wiphy_debug(local->hw.wiphy,
01347                             "failed to set TX queue parameters for queue %d\n",
01348                             params->queue);
01349                 return -EINVAL;
01350         }
01351 
01352         return 0;
01353 }
01354 
01355 static int ieee80211_set_channel(struct wiphy *wiphy,
01356                                  struct net_device *netdev,
01357                                  struct ieee80211_channel *chan,
01358                                  enum nl80211_channel_type channel_type)
01359 {
01360         struct ieee80211_local *local = wiphy_priv(wiphy);
01361         struct ieee80211_sub_if_data *sdata = NULL;
01362         struct ieee80211_channel *old_oper;
01363         enum nl80211_channel_type old_oper_type;
01364         enum nl80211_channel_type old_vif_oper_type= NL80211_CHAN_NO_HT;
01365 
01366         if (netdev)
01367                 sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
01368 
01369         switch (ieee80211_get_channel_mode(local, NULL)) {
01370         case CHAN_MODE_HOPPING:
01371                 return -EBUSY;
01372         case CHAN_MODE_FIXED:
01373                 if (local->oper_channel != chan)
01374                         return -EBUSY;
01375                 if (!sdata && local->_oper_channel_type == channel_type)
01376                         return 0;
01377                 break;
01378         case CHAN_MODE_UNDEFINED:
01379                 break;
01380         }
01381 
01382         if (sdata)
01383                 old_vif_oper_type = sdata->vif.bss_conf.channel_type;
01384         old_oper_type = local->_oper_channel_type;
01385 
01386         if (!ieee80211_set_channel_type(local, sdata, channel_type))
01387                 return -EBUSY;
01388 
01389         old_oper = local->oper_channel;
01390         local->oper_channel = chan;
01391 
01392         /* Update driver if changes were actually made. */
01393         if ((old_oper != local->oper_channel) ||
01394             (old_oper_type != local->_oper_channel_type))
01395                 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
01396 
01397         if ((sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) &&
01398             old_vif_oper_type != sdata->vif.bss_conf.channel_type)
01399                 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
01400 
01401         return 0;
01402 }
01403 
01404 #ifdef CONFIG_PM
01405 static int ieee80211_suspend(struct wiphy *wiphy,
01406                              struct cfg80211_wowlan *wowlan)
01407 {
01408         return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
01409 }
01410 
01411 static int ieee80211_resume(struct wiphy *wiphy)
01412 {
01413         return __ieee80211_resume(wiphy_priv(wiphy));
01414 }
01415 #else
01416 #define ieee80211_suspend NULL
01417 #define ieee80211_resume NULL
01418 #endif
01419 
01420 static int ieee80211_scan(struct wiphy *wiphy,
01421                           struct net_device *dev,
01422                           struct cfg80211_scan_request *req)
01423 {
01424         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01425 
01426         switch (ieee80211_vif_type_p2p(&sdata->vif)) {
01427         case NL80211_IFTYPE_STATION:
01428         case NL80211_IFTYPE_ADHOC:
01429         case NL80211_IFTYPE_MESH_POINT:
01430         case NL80211_IFTYPE_P2P_CLIENT:
01431                 break;
01432         case NL80211_IFTYPE_P2P_GO:
01433                 if (sdata->local->ops->hw_scan)
01434                         break;
01435                 /*
01436                  * FIXME: implement NoA while scanning in software,
01437                  * for now fall through to allow scanning only when
01438                  * beaconing hasn't been configured yet
01439                  */
01440         case NL80211_IFTYPE_AP:
01441                 if (sdata->u.ap.beacon)
01442                         return -EOPNOTSUPP;
01443                 break;
01444         default:
01445                 return -EOPNOTSUPP;
01446         }
01447 
01448         return ieee80211_request_scan(sdata, req);
01449 }
01450 
01451 static int
01452 ieee80211_sched_scan_start(struct wiphy *wiphy,
01453                            struct net_device *dev,
01454                            struct cfg80211_sched_scan_request *req)
01455 {
01456         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01457 
01458         if (!sdata->local->ops->sched_scan_start)
01459                 return -EOPNOTSUPP;
01460 
01461         return ieee80211_request_sched_scan_start(sdata, req);
01462 }
01463 
01464 static int
01465 ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
01466 {
01467         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01468 
01469         if (!sdata->local->ops->sched_scan_stop)
01470                 return -EOPNOTSUPP;
01471 
01472         return ieee80211_request_sched_scan_stop(sdata);
01473 }
01474 
01475 static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
01476                           struct cfg80211_auth_request *req)
01477 {
01478         return ieee80211_mgd_auth(IEEE80211_DEV_TO_SUB_IF(dev), req);
01479 }
01480 
01481 static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
01482                            struct cfg80211_assoc_request *req)
01483 {
01484         struct ieee80211_local *local = wiphy_priv(wiphy);
01485         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01486 
01487         switch (ieee80211_get_channel_mode(local, sdata)) {
01488         case CHAN_MODE_HOPPING:
01489                 return -EBUSY;
01490         case CHAN_MODE_FIXED:
01491                 if (local->oper_channel == req->bss->channel)
01492                         break;
01493                 return -EBUSY;
01494         case CHAN_MODE_UNDEFINED:
01495                 break;
01496         }
01497 
01498         return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
01499 }
01500 
01501 static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
01502                             struct cfg80211_deauth_request *req,
01503                             void *cookie)
01504 {
01505         return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev),
01506                                     req, cookie);
01507 }
01508 
01509 static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
01510                               struct cfg80211_disassoc_request *req,
01511                               void *cookie)
01512 {
01513         return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev),
01514                                       req, cookie);
01515 }
01516 
01517 static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
01518                                struct cfg80211_ibss_params *params)
01519 {
01520         struct ieee80211_local *local = wiphy_priv(wiphy);
01521         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01522 
01523         switch (ieee80211_get_channel_mode(local, sdata)) {
01524         case CHAN_MODE_HOPPING:
01525                 return -EBUSY;
01526         case CHAN_MODE_FIXED:
01527                 if (!params->channel_fixed)
01528                         return -EBUSY;
01529                 if (local->oper_channel == params->channel)
01530                         break;
01531                 return -EBUSY;
01532         case CHAN_MODE_UNDEFINED:
01533                 break;
01534         }
01535 
01536         return ieee80211_ibss_join(sdata, params);
01537 }
01538 
01539 static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
01540 {
01541         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01542 
01543         return ieee80211_ibss_leave(sdata);
01544 }
01545 
01546 static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
01547 {
01548         struct ieee80211_local *local = wiphy_priv(wiphy);
01549         int err;
01550 
01551         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
01552                 err = drv_set_frag_threshold(local, wiphy->frag_threshold);
01553 
01554                 if (err)
01555                         return err;
01556         }
01557 
01558         if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
01559                 err = drv_set_coverage_class(local, wiphy->coverage_class);
01560 
01561                 if (err)
01562                         return err;
01563         }
01564 
01565         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
01566                 err = drv_set_rts_threshold(local, wiphy->rts_threshold);
01567 
01568                 if (err)
01569                         return err;
01570         }
01571 
01572         if (changed & WIPHY_PARAM_RETRY_SHORT)
01573                 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
01574         if (changed & WIPHY_PARAM_RETRY_LONG)
01575                 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
01576         if (changed &
01577             (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
01578                 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
01579 
01580         return 0;
01581 }
01582 
01583 static int ieee80211_set_tx_power(struct wiphy *wiphy,
01584                                   enum nl80211_tx_power_setting type, int mbm)
01585 {
01586         struct ieee80211_local *local = wiphy_priv(wiphy);
01587         struct ieee80211_channel *chan = local->hw.conf.channel;
01588         u32 changes = 0;
01589 
01590         switch (type) {
01591         case NL80211_TX_POWER_AUTOMATIC:
01592                 local->user_power_level = -1;
01593                 break;
01594         case NL80211_TX_POWER_LIMITED:
01595                 if (mbm < 0 || (mbm % 100))
01596                         return -EOPNOTSUPP;
01597                 local->user_power_level = MBM_TO_DBM(mbm);
01598                 break;
01599         case NL80211_TX_POWER_FIXED:
01600                 if (mbm < 0 || (mbm % 100))
01601                         return -EOPNOTSUPP;
01602                 /* TODO: move to cfg80211 when it knows the channel */
01603                 if (MBM_TO_DBM(mbm) > chan->max_power)
01604                         return -EINVAL;
01605                 local->user_power_level = MBM_TO_DBM(mbm);
01606                 break;
01607         }
01608 
01609         ieee80211_hw_config(local, changes);
01610 
01611         return 0;
01612 }
01613 
01614 static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
01615 {
01616         struct ieee80211_local *local = wiphy_priv(wiphy);
01617 
01618         *dbm = local->hw.conf.power_level;
01619 
01620         return 0;
01621 }
01622 
01623 static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
01624                                   const u8 *addr)
01625 {
01626         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01627 
01628         memcpy(&sdata->u.wds.remote_addr, addr, ETH_ALEN);
01629 
01630         return 0;
01631 }
01632 
01633 static void ieee80211_rfkill_poll(struct wiphy *wiphy)
01634 {
01635         struct ieee80211_local *local = wiphy_priv(wiphy);
01636 
01637         drv_rfkill_poll(local);
01638 }
01639 
01640 #ifdef CONFIG_NL80211_TESTMODE
01641 static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
01642 {
01643         struct ieee80211_local *local = wiphy_priv(wiphy);
01644 
01645         if (!local->ops->testmode_cmd)
01646                 return -EOPNOTSUPP;
01647 
01648         return local->ops->testmode_cmd(&local->hw, data, len);
01649 }
01650 
01651 static int ieee80211_testmode_dump(struct wiphy *wiphy,
01652                                    struct sk_buff *skb,
01653                                    struct netlink_callback *cb,
01654                                    void *data, int len)
01655 {
01656         struct ieee80211_local *local = wiphy_priv(wiphy);
01657 
01658         if (!local->ops->testmode_dump)
01659                 return -EOPNOTSUPP;
01660 
01661         return local->ops->testmode_dump(&local->hw, skb, cb, data, len);
01662 }
01663 #endif
01664 
01665 int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
01666                              enum ieee80211_smps_mode smps_mode)
01667 {
01668         const u8 *ap;
01669         enum ieee80211_smps_mode old_req;
01670         int err;
01671 
01672         lockdep_assert_held(&sdata->u.mgd.mtx);
01673 
01674         old_req = sdata->u.mgd.req_smps;
01675         sdata->u.mgd.req_smps = smps_mode;
01676 
01677         if (old_req == smps_mode &&
01678             smps_mode != IEEE80211_SMPS_AUTOMATIC)
01679                 return 0;
01680 
01681         /*
01682          * If not associated, or current association is not an HT
01683          * association, there's no need to send an action frame.
01684          */
01685         if (!sdata->u.mgd.associated ||
01686             sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
01687                 mutex_lock(&sdata->local->iflist_mtx);
01688                 ieee80211_recalc_smps(sdata->local);
01689                 mutex_unlock(&sdata->local->iflist_mtx);
01690                 return 0;
01691         }
01692 
01693         ap = sdata->u.mgd.associated->bssid;
01694 
01695         if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
01696                 if (sdata->u.mgd.powersave)
01697                         smps_mode = IEEE80211_SMPS_DYNAMIC;
01698                 else
01699                         smps_mode = IEEE80211_SMPS_OFF;
01700         }
01701 
01702         /* send SM PS frame to AP */
01703         err = ieee80211_send_smps_action(sdata, smps_mode,
01704                                          ap, ap);
01705         if (err)
01706                 sdata->u.mgd.req_smps = old_req;
01707 
01708         return err;
01709 }
01710 
01711 static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
01712                                     bool enabled, int timeout)
01713 {
01714         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01715         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
01716 
01717         if (sdata->vif.type != NL80211_IFTYPE_STATION)
01718                 return -EOPNOTSUPP;
01719 
01720         if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
01721                 return -EOPNOTSUPP;
01722 
01723         if (enabled == sdata->u.mgd.powersave &&
01724             timeout == local->dynamic_ps_forced_timeout)
01725                 return 0;
01726 
01727         sdata->u.mgd.powersave = enabled;
01728         local->dynamic_ps_forced_timeout = timeout;
01729 
01730         /* no change, but if automatic follow powersave */
01731         mutex_lock(&sdata->u.mgd.mtx);
01732         __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
01733         mutex_unlock(&sdata->u.mgd.mtx);
01734 
01735         if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
01736                 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
01737 
01738         ieee80211_recalc_ps(local, -1);
01739 
01740         return 0;
01741 }
01742 
01743 static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
01744                                          struct net_device *dev,
01745                                          s32 rssi_thold, u32 rssi_hyst)
01746 {
01747         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01748         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
01749         struct ieee80211_vif *vif = &sdata->vif;
01750         struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
01751 
01752         if (rssi_thold == bss_conf->cqm_rssi_thold &&
01753             rssi_hyst == bss_conf->cqm_rssi_hyst)
01754                 return 0;
01755 
01756         bss_conf->cqm_rssi_thold = rssi_thold;
01757         bss_conf->cqm_rssi_hyst = rssi_hyst;
01758 
01759         if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
01760                 if (sdata->vif.type != NL80211_IFTYPE_STATION)
01761                         return -EOPNOTSUPP;
01762                 return 0;
01763         }
01764 
01765         /* tell the driver upon association, unless already associated */
01766         if (sdata->u.mgd.associated)
01767                 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
01768 
01769         return 0;
01770 }
01771 
01772 static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
01773                                       struct net_device *dev,
01774                                       const u8 *addr,
01775                                       const struct cfg80211_bitrate_mask *mask)
01776 {
01777         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01778         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
01779         int i, ret;
01780 
01781         if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) {
01782                 ret = drv_set_bitrate_mask(local, sdata, mask);
01783                 if (ret)
01784                         return ret;
01785         }
01786 
01787         for (i = 0; i < IEEE80211_NUM_BANDS; i++)
01788                 sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
01789 
01790         return 0;
01791 }
01792 
01793 static int ieee80211_remain_on_channel_hw(struct ieee80211_local *local,
01794                                           struct net_device *dev,
01795                                           struct ieee80211_channel *chan,
01796                                           enum nl80211_channel_type chantype,
01797                                           unsigned int duration, u64 *cookie)
01798 {
01799         int ret;
01800         u32 random_cookie;
01801 
01802         lockdep_assert_held(&local->mtx);
01803 
01804         if (local->hw_roc_cookie)
01805                 return -EBUSY;
01806         /* must be nonzero */
01807         random_cookie = random32() | 1;
01808 
01809         *cookie = random_cookie;
01810         local->hw_roc_dev = dev;
01811         local->hw_roc_cookie = random_cookie;
01812         local->hw_roc_channel = chan;
01813         local->hw_roc_channel_type = chantype;
01814         local->hw_roc_duration = duration;
01815         ret = drv_remain_on_channel(local, chan, chantype, duration);
01816         if (ret) {
01817                 local->hw_roc_channel = NULL;
01818                 local->hw_roc_cookie = 0;
01819         }
01820 
01821         return ret;
01822 }
01823 
01824 static int ieee80211_remain_on_channel(struct wiphy *wiphy,
01825                                        struct net_device *dev,
01826                                        struct ieee80211_channel *chan,
01827                                        enum nl80211_channel_type channel_type,
01828                                        unsigned int duration,
01829                                        u64 *cookie)
01830 {
01831         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01832         struct ieee80211_local *local = sdata->local;
01833 
01834         if (local->ops->remain_on_channel) {
01835                 int ret;
01836 
01837                 mutex_lock(&local->mtx);
01838                 ret = ieee80211_remain_on_channel_hw(local, dev,
01839                                                      chan, channel_type,
01840                                                      duration, cookie);
01841                 local->hw_roc_for_tx = false;
01842                 mutex_unlock(&local->mtx);
01843 
01844                 return ret;
01845         }
01846 
01847         return ieee80211_wk_remain_on_channel(sdata, chan, channel_type,
01848                                               duration, cookie);
01849 }
01850 
01851 static int ieee80211_cancel_remain_on_channel_hw(struct ieee80211_local *local,
01852                                                  u64 cookie)
01853 {
01854         int ret;
01855 
01856         lockdep_assert_held(&local->mtx);
01857 
01858         if (local->hw_roc_cookie != cookie)
01859                 return -ENOENT;
01860 
01861         ret = drv_cancel_remain_on_channel(local);
01862         if (ret)
01863                 return ret;
01864 
01865         local->hw_roc_cookie = 0;
01866         local->hw_roc_channel = NULL;
01867 
01868         ieee80211_recalc_idle(local);
01869 
01870         return 0;
01871 }
01872 
01873 static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
01874                                               struct net_device *dev,
01875                                               u64 cookie)
01876 {
01877         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01878         struct ieee80211_local *local = sdata->local;
01879 
01880         if (local->ops->cancel_remain_on_channel) {
01881                 int ret;
01882 
01883                 mutex_lock(&local->mtx);
01884                 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie);
01885                 mutex_unlock(&local->mtx);
01886 
01887                 return ret;
01888         }
01889 
01890         return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
01891 }
01892 
01893 static enum work_done_result
01894 ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)
01895 {
01896         /*
01897          * Use the data embedded in the work struct for reporting
01898          * here so if the driver mangled the SKB before dropping
01899          * it (which is the only way we really should get here)
01900          * then we don't report mangled data.
01901          *
01902          * If there was no wait time, then by the time we get here
01903          * the driver will likely not have reported the status yet,
01904          * so in that case userspace will have to deal with it.
01905          */
01906 
01907         if (wk->offchan_tx.wait && !wk->offchan_tx.status)
01908                 cfg80211_mgmt_tx_status(wk->sdata->dev,
01909                                         (unsigned long) wk->offchan_tx.frame,
01910                                         wk->ie, wk->ie_len, false, GFP_KERNEL);
01911 
01912         return WORK_DONE_DESTROY;
01913 }
01914 
01915 static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
01916                              struct ieee80211_channel *chan, bool offchan,
01917                              enum nl80211_channel_type channel_type,
01918                              bool channel_type_valid, unsigned int wait,
01919                              const u8 *buf, size_t len, bool no_cck,
01920                              u64 *cookie)
01921 {
01922         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
01923         struct ieee80211_local *local = sdata->local;
01924         struct sk_buff *skb;
01925         struct sta_info *sta;
01926         struct ieee80211_work *wk;
01927         const struct ieee80211_mgmt *mgmt = (void *)buf;
01928         u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
01929                     IEEE80211_TX_CTL_REQ_TX_STATUS;
01930         bool is_offchan = false;
01931 
01932         /* Check that we are on the requested channel for transmission */
01933         if (chan != local->tmp_channel &&
01934             chan != local->oper_channel)
01935                 is_offchan = true;
01936         if (channel_type_valid &&
01937             (channel_type != local->tmp_channel_type &&
01938              channel_type != local->_oper_channel_type))
01939                 is_offchan = true;
01940 
01941         if (chan == local->hw_roc_channel) {
01942                 /* TODO: check channel type? */
01943                 is_offchan = false;
01944                 flags |= IEEE80211_TX_CTL_TX_OFFCHAN;
01945         }
01946 
01947         if (no_cck)
01948                 flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
01949 
01950         if (is_offchan && !offchan)
01951                 return -EBUSY;
01952 
01953         switch (sdata->vif.type) {
01954         case NL80211_IFTYPE_ADHOC:
01955         case NL80211_IFTYPE_AP:
01956         case NL80211_IFTYPE_AP_VLAN:
01957         case NL80211_IFTYPE_P2P_GO:
01958         case NL80211_IFTYPE_MESH_POINT:
01959                 if (!ieee80211_is_action(mgmt->frame_control) ||
01960                     mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
01961                         break;
01962                 rcu_read_lock();
01963                 sta = sta_info_get(sdata, mgmt->da);
01964                 rcu_read_unlock();
01965                 if (!sta)
01966                         return -ENOLINK;
01967                 break;
01968         case NL80211_IFTYPE_STATION:
01969         case NL80211_IFTYPE_P2P_CLIENT:
01970                 break;
01971         default:
01972                 return -EOPNOTSUPP;
01973         }
01974 
01975         skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
01976         if (!skb)
01977                 return -ENOMEM;
01978         skb_reserve(skb, local->hw.extra_tx_headroom);
01979 
01980         memcpy(skb_put(skb, len), buf, len);
01981 
01982         IEEE80211_SKB_CB(skb)->flags = flags;
01983 
01984         skb->dev = sdata->dev;
01985 
01986         *cookie = (unsigned long) skb;
01987 
01988         if (is_offchan && local->ops->remain_on_channel) {
01989                 unsigned int duration;
01990                 int ret;
01991 
01992                 mutex_lock(&local->mtx);
01993                 /*
01994                  * If the duration is zero, then the driver
01995                  * wouldn't actually do anything. Set it to
01996                  * 100 for now.
01997                  *
01998                  * TODO: cancel the off-channel operation
01999                  *       when we get the SKB's TX status and
02000                  *       the wait time was zero before.
02001                  */
02002                 duration = 100;
02003                 if (wait)
02004                         duration = wait;
02005                 ret = ieee80211_remain_on_channel_hw(local, dev, chan,
02006                                                      channel_type,
02007                                                      duration, cookie);
02008                 if (ret) {
02009                         kfree_skb(skb);
02010                         mutex_unlock(&local->mtx);
02011                         return ret;
02012                 }
02013 
02014                 local->hw_roc_for_tx = true;
02015                 local->hw_roc_duration = wait;
02016 
02017                 /*
02018                  * queue up frame for transmission after
02019                  * ieee80211_ready_on_channel call
02020                  */
02021 
02022                 /* modify cookie to prevent API mismatches */
02023                 *cookie ^= 2;
02024                 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN;
02025                 local->hw_roc_skb = skb;
02026                 local->hw_roc_skb_for_status = skb;
02027                 mutex_unlock(&local->mtx);
02028 
02029                 return 0;
02030         }
02031 
02032         /*
02033          * Can transmit right away if the channel was the
02034          * right one and there's no wait involved... If a
02035          * wait is involved, we might otherwise not be on
02036          * the right channel for long enough!
02037          */
02038         if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) {
02039                 ieee80211_tx_skb(sdata, skb);
02040                 return 0;
02041         }
02042 
02043         wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL);
02044         if (!wk) {
02045                 kfree_skb(skb);
02046                 return -ENOMEM;
02047         }
02048 
02049         wk->type = IEEE80211_WORK_OFFCHANNEL_TX;
02050         wk->chan = chan;
02051         wk->chan_type = channel_type;
02052         wk->sdata = sdata;
02053         wk->done = ieee80211_offchan_tx_done;
02054         wk->offchan_tx.frame = skb;
02055         wk->offchan_tx.wait = wait;
02056         wk->ie_len = len;
02057         memcpy(wk->ie, buf, len);
02058 
02059         ieee80211_add_work(wk);
02060         return 0;
02061 }
02062 
02063 static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
02064                                          struct net_device *dev,
02065                                          u64 cookie)
02066 {
02067         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
02068         struct ieee80211_local *local = sdata->local;
02069         struct ieee80211_work *wk;
02070         int ret = -ENOENT;
02071 
02072         mutex_lock(&local->mtx);
02073 
02074         if (local->ops->cancel_remain_on_channel) {
02075                 cookie ^= 2;
02076                 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie);
02077 
02078                 if (ret == 0) {
02079                         kfree_skb(local->hw_roc_skb);
02080                         local->hw_roc_skb = NULL;
02081                         local->hw_roc_skb_for_status = NULL;
02082                 }
02083 
02084                 mutex_unlock(&local->mtx);
02085 
02086                 return ret;
02087         }
02088 
02089         list_for_each_entry(wk, &local->work_list, list) {
02090                 if (wk->sdata != sdata)
02091                         continue;
02092 
02093                 if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
02094                         continue;
02095 
02096                 if (cookie != (unsigned long) wk->offchan_tx.frame)
02097                         continue;
02098 
02099                 wk->timeout = jiffies;
02100 
02101                 ieee80211_queue_work(&local->hw, &local->work_work);
02102                 ret = 0;
02103                 break;
02104         }
02105         mutex_unlock(&local->mtx);
02106 
02107         return ret;
02108 }
02109 
02110 static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
02111                                           struct net_device *dev,
02112                                           u16 frame_type, bool reg)
02113 {
02114         struct ieee80211_local *local = wiphy_priv(wiphy);
02115 
02116         if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
02117                 return;
02118 
02119         if (reg)
02120                 local->probe_req_reg++;
02121         else
02122                 local->probe_req_reg--;
02123 
02124         ieee80211_queue_work(&local->hw, &local->reconfig_filter);
02125 }
02126 
02127 static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
02128 {
02129         struct ieee80211_local *local = wiphy_priv(wiphy);
02130 
02131         if (local->started)
02132                 return -EOPNOTSUPP;
02133 
02134         return drv_set_antenna(local, tx_ant, rx_ant);
02135 }
02136 
02137 static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
02138 {
02139         struct ieee80211_local *local = wiphy_priv(wiphy);
02140 
02141         return drv_get_antenna(local, tx_ant, rx_ant);
02142 }
02143 
02144 static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx)
02145 {
02146         struct ieee80211_local *local = wiphy_priv(wiphy);
02147 
02148         return drv_set_ringparam(local, tx, rx);
02149 }
02150 
02151 static void ieee80211_get_ringparam(struct wiphy *wiphy,
02152                                     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
02153 {
02154         struct ieee80211_local *local = wiphy_priv(wiphy);
02155 
02156         drv_get_ringparam(local, tx, tx_max, rx, rx_max);
02157 }
02158 
02159 static int ieee80211_set_rekey_data(struct wiphy *wiphy,
02160                                     struct net_device *dev,
02161                                     struct cfg80211_gtk_rekey_data *data)
02162 {
02163         struct ieee80211_local *local = wiphy_priv(wiphy);
02164         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
02165 
02166         if (!local->ops->set_rekey_data)
02167                 return -EOPNOTSUPP;
02168 
02169         drv_set_rekey_data(local, sdata, data);
02170 
02171         return 0;
02172 }
02173 
02174 static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
02175 {
02176         u8 *pos = (void *)skb_put(skb, 7);
02177 
02178         *pos++ = WLAN_EID_EXT_CAPABILITY;
02179         *pos++ = 5; /* len */
02180         *pos++ = 0x0;
02181         *pos++ = 0x0;
02182         *pos++ = 0x0;
02183         *pos++ = 0x0;
02184         *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
02185 }
02186 
02187 static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata)
02188 {
02189         struct ieee80211_local *local = sdata->local;
02190         u16 capab;
02191 
02192         capab = 0;
02193         if (local->oper_channel->band != IEEE80211_BAND_2GHZ)
02194                 return capab;
02195 
02196         if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
02197                 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
02198         if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
02199                 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
02200 
02201         return capab;
02202 }
02203 
02204 static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr,
02205                                        u8 *peer, u8 *bssid)
02206 {
02207         struct ieee80211_tdls_lnkie *lnkid;
02208 
02209         lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
02210 
02211         lnkid->ie_type = WLAN_EID_LINK_ID;
02212         lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
02213 
02214         memcpy(lnkid->bssid, bssid, ETH_ALEN);
02215         memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
02216         memcpy(lnkid->resp_sta, peer, ETH_ALEN);
02217 }
02218 
02219 static int
02220 ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
02221                                u8 *peer, u8 action_code, u8 dialog_token,
02222                                u16 status_code, struct sk_buff *skb)
02223 {
02224         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
02225         struct ieee80211_tdls_data *tf;
02226 
02227         tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
02228 
02229         memcpy(tf->da, peer, ETH_ALEN);
02230         memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
02231         tf->ether_type = cpu_to_be16(ETH_P_TDLS);
02232         tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
02233 
02234         switch (action_code) {
02235         case WLAN_TDLS_SETUP_REQUEST:
02236                 tf->category = WLAN_CATEGORY_TDLS;
02237                 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
02238 
02239                 skb_put(skb, sizeof(tf->u.setup_req));
02240                 tf->u.setup_req.dialog_token = dialog_token;
02241                 tf->u.setup_req.capability =
02242                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
02243 
02244                 ieee80211_add_srates_ie(&sdata->vif, skb);
02245                 ieee80211_add_ext_srates_ie(&sdata->vif, skb);
02246                 ieee80211_tdls_add_ext_capab(skb);
02247                 break;
02248         case WLAN_TDLS_SETUP_RESPONSE:
02249                 tf->category = WLAN_CATEGORY_TDLS;
02250                 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
02251 
02252                 skb_put(skb, sizeof(tf->u.setup_resp));
02253                 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
02254                 tf->u.setup_resp.dialog_token = dialog_token;
02255                 tf->u.setup_resp.capability =
02256                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
02257 
02258                 ieee80211_add_srates_ie(&sdata->vif, skb);
02259                 ieee80211_add_ext_srates_ie(&sdata->vif, skb);
02260                 ieee80211_tdls_add_ext_capab(skb);
02261                 break;
02262         case WLAN_TDLS_SETUP_CONFIRM:
02263                 tf->category = WLAN_CATEGORY_TDLS;
02264                 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
02265 
02266                 skb_put(skb, sizeof(tf->u.setup_cfm));
02267                 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
02268                 tf->u.setup_cfm.dialog_token = dialog_token;
02269                 break;
02270         case WLAN_TDLS_TEARDOWN:
02271                 tf->category = WLAN_CATEGORY_TDLS;
02272                 tf->action_code = WLAN_TDLS_TEARDOWN;
02273 
02274                 skb_put(skb, sizeof(tf->u.teardown));
02275                 tf->u.teardown.reason_code = cpu_to_le16(status_code);
02276                 break;
02277         case WLAN_TDLS_DISCOVERY_REQUEST:
02278                 tf->category = WLAN_CATEGORY_TDLS;
02279                 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
02280 
02281                 skb_put(skb, sizeof(tf->u.discover_req));
02282                 tf->u.discover_req.dialog_token = dialog_token;
02283                 break;
02284         default:
02285                 return -EINVAL;
02286         }
02287 
02288         return 0;
02289 }
02290 
02291 static int
02292 ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
02293                            u8 *peer, u8 action_code, u8 dialog_token,
02294                            u16 status_code, struct sk_buff *skb)
02295 {
02296         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
02297         struct ieee80211_mgmt *mgmt;
02298 
02299         mgmt = (void *)skb_put(skb, 24);
02300         memset(mgmt, 0, 24);
02301         memcpy(mgmt->da, peer, ETH_ALEN);
02302         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
02303         memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
02304 
02305         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
02306                                           IEEE80211_STYPE_ACTION);
02307 
02308         switch (action_code) {
02309         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
02310                 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
02311                 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
02312                 mgmt->u.action.u.tdls_discover_resp.action_code =
02313                         WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
02314                 mgmt->u.action.u.tdls_discover_resp.dialog_token =
02315                         dialog_token;
02316                 mgmt->u.action.u.tdls_discover_resp.capability =
02317                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
02318 
02319                 ieee80211_add_srates_ie(&sdata->vif, skb);
02320                 ieee80211_add_ext_srates_ie(&sdata->vif, skb);
02321                 ieee80211_tdls_add_ext_capab(skb);
02322                 break;
02323         default:
02324                 return -EINVAL;
02325         }
02326 
02327         return 0;
02328 }
02329 
02330 static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
02331                                u8 *peer, u8 action_code, u8 dialog_token,
02332                                u16 status_code, const u8 *extra_ies,
02333                                size_t extra_ies_len)
02334 {
02335         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
02336         struct ieee80211_local *local = sdata->local;
02337         struct ieee80211_tx_info *info;
02338         struct sk_buff *skb = NULL;
02339         bool send_direct;
02340         int ret;
02341 
02342         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
02343                 return -ENOTSUPP;
02344 
02345         /* make sure we are in managed mode, and associated */
02346         if (sdata->vif.type != NL80211_IFTYPE_STATION ||
02347             !sdata->u.mgd.associated)
02348                 return -EINVAL;
02349 
02350 #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
02351         printk(KERN_DEBUG "TDLS mgmt action %d peer %pM\n", action_code, peer);
02352 #endif
02353 
02354         skb = dev_alloc_skb(local->hw.extra_tx_headroom +
02355                             max(sizeof(struct ieee80211_mgmt),
02356                                 sizeof(struct ieee80211_tdls_data)) +
02357                             50 + /* supported rates */
02358                             7 + /* ext capab */
02359                             extra_ies_len +
02360                             sizeof(struct ieee80211_tdls_lnkie));
02361         if (!skb)
02362                 return -ENOMEM;
02363 
02364         info = IEEE80211_SKB_CB(skb);
02365         skb_reserve(skb, local->hw.extra_tx_headroom);
02366 
02367         switch (action_code) {
02368         case WLAN_TDLS_SETUP_REQUEST:
02369         case WLAN_TDLS_SETUP_RESPONSE:
02370         case WLAN_TDLS_SETUP_CONFIRM:
02371         case WLAN_TDLS_TEARDOWN:
02372         case WLAN_TDLS_DISCOVERY_REQUEST:
02373                 ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
02374                                                      action_code, dialog_token,
02375                                                      status_code, skb);
02376                 send_direct = false;
02377                 break;
02378         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
02379                 ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
02380                                                  dialog_token, status_code,
02381                                                  skb);
02382                 send_direct = true;
02383                 break;
02384         default:
02385                 ret = -ENOTSUPP;
02386                 break;
02387         }
02388 
02389         if (ret < 0)
02390                 goto fail;
02391 
02392         if (extra_ies_len)
02393                 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
02394 
02395         /* the TDLS link IE is always added last */
02396         switch (action_code) {
02397         case WLAN_TDLS_SETUP_REQUEST:
02398         case WLAN_TDLS_SETUP_CONFIRM:
02399         case WLAN_TDLS_TEARDOWN:
02400         case WLAN_TDLS_DISCOVERY_REQUEST:
02401                 /* we are the initiator */
02402                 ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer,
02403                                            sdata->u.mgd.bssid);
02404                 break;
02405         case WLAN_TDLS_SETUP_RESPONSE:
02406         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
02407                 /* we are the responder */
02408                 ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr,
02409                                            sdata->u.mgd.bssid);
02410                 break;
02411         default:
02412                 ret = -ENOTSUPP;
02413                 goto fail;
02414         }
02415 
02416         if (send_direct) {
02417                 ieee80211_tx_skb(sdata, skb);
02418                 return 0;
02419         }
02420 
02421         /*
02422          * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
02423          * we should default to AC_VI.
02424          */
02425         switch (action_code) {
02426         case WLAN_TDLS_SETUP_REQUEST:
02427         case WLAN_TDLS_SETUP_RESPONSE:
02428                 skb_set_queue_mapping(skb, IEEE80211_AC_BK);
02429                 skb->priority = 2;
02430                 break;
02431         default:
02432                 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
02433                 skb->priority = 5;
02434                 break;
02435         }
02436 
02437         /* disable bottom halves when entering the Tx path */
02438         local_bh_disable();
02439         ret = ieee80211_subif_start_xmit(skb, dev);
02440         local_bh_enable();
02441 
02442         return ret;
02443 
02444 fail:
02445         dev_kfree_skb(skb);
02446         return ret;
02447 }
02448 
02449 static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
02450                                u8 *peer, enum nl80211_tdls_operation oper)
02451 {
02452         struct sta_info *sta;
02453         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
02454 
02455         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
02456                 return -ENOTSUPP;
02457 
02458         if (sdata->vif.type != NL80211_IFTYPE_STATION)
02459                 return -EINVAL;
02460 
02461 #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
02462         printk(KERN_DEBUG "TDLS oper %d peer %pM\n", oper, peer);
02463 #endif
02464 
02465         switch (oper) {
02466         case NL80211_TDLS_ENABLE_LINK:
02467                 rcu_read_lock();
02468                 sta = sta_info_get(sdata, peer);
02469                 if (!sta) {
02470                         rcu_read_unlock();
02471                         return -ENOLINK;
02472                 }
02473 
02474                 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
02475                 rcu_read_unlock();
02476                 break;
02477         case NL80211_TDLS_DISABLE_LINK:
02478                 return sta_info_destroy_addr(sdata, peer);
02479         case NL80211_TDLS_TEARDOWN:
02480         case NL80211_TDLS_SETUP:
02481         case NL80211_TDLS_DISCOVERY_REQ:
02482                 /* We don't support in-driver setup/teardown/discovery */
02483                 return -ENOTSUPP;
02484         default:
02485                 return -ENOTSUPP;
02486         }
02487 
02488         return 0;
02489 }
02490 
02491 struct cfg80211_ops mac80211_config_ops = {
02492         .add_virtual_intf = ieee80211_add_iface,
02493         .del_virtual_intf = ieee80211_del_iface,
02494         .change_virtual_intf = ieee80211_change_iface,
02495         .add_key = ieee80211_add_key,
02496         .del_key = ieee80211_del_key,
02497         .get_key = ieee80211_get_key,
02498         .set_default_key = ieee80211_config_default_key,
02499         .set_default_mgmt_key = ieee80211_config_default_mgmt_key,
02500         .add_beacon = ieee80211_add_beacon,
02501         .set_beacon = ieee80211_set_beacon,
02502         .del_beacon = ieee80211_del_beacon,
02503         .add_station = ieee80211_add_station,
02504         .del_station = ieee80211_del_station,
02505         .change_station = ieee80211_change_station,
02506         .get_station = ieee80211_get_station,
02507         .dump_station = ieee80211_dump_station,
02508         .dump_survey = ieee80211_dump_survey,
02509 #ifdef CONFIG_MAC80211_MESH
02510         .add_mpath = ieee80211_add_mpath,
02511         .del_mpath = ieee80211_del_mpath,
02512         .change_mpath = ieee80211_change_mpath,
02513         .get_mpath = ieee80211_get_mpath,
02514         .dump_mpath = ieee80211_dump_mpath,
02515         .update_mesh_config = ieee80211_update_mesh_config,
02516         .get_mesh_config = ieee80211_get_mesh_config,
02517         .join_mesh = ieee80211_join_mesh,
02518         .leave_mesh = ieee80211_leave_mesh,
02519 #endif
02520         .change_bss = ieee80211_change_bss,
02521         .set_txq_params = ieee80211_set_txq_params,
02522         .set_channel = ieee80211_set_channel,
02523         .suspend = ieee80211_suspend,
02524         .resume = ieee80211_resume,
02525         .scan = ieee80211_scan,
02526         .sched_scan_start = ieee80211_sched_scan_start,
02527         .sched_scan_stop = ieee80211_sched_scan_stop,
02528         .auth = ieee80211_auth,
02529         .assoc = ieee80211_assoc,
02530         .deauth = ieee80211_deauth,
02531         .disassoc = ieee80211_disassoc,
02532         .join_ibss = ieee80211_join_ibss,
02533         .leave_ibss = ieee80211_leave_ibss,
02534         .set_wiphy_params = ieee80211_set_wiphy_params,
02535         .set_tx_power = ieee80211_set_tx_power,
02536         .get_tx_power = ieee80211_get_tx_power,
02537         .set_wds_peer = ieee80211_set_wds_peer,
02538         .rfkill_poll = ieee80211_rfkill_poll,
02539         CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
02540         CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
02541         .set_power_mgmt = ieee80211_set_power_mgmt,
02542         .set_bitrate_mask = ieee80211_set_bitrate_mask,
02543         .remain_on_channel = ieee80211_remain_on_channel,
02544         .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
02545         .mgmt_tx = ieee80211_mgmt_tx,
02546         .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,
02547         .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
02548         .mgmt_frame_register = ieee80211_mgmt_frame_register,
02549         .set_antenna = ieee80211_set_antenna,
02550         .get_antenna = ieee80211_get_antenna,
02551         .set_ringparam = ieee80211_set_ringparam,
02552         .get_ringparam = ieee80211_get_ringparam,
02553         .set_rekey_data = ieee80211_set_rekey_data,
02554         .tdls_oper = ieee80211_tdls_oper,
02555         .tdls_mgmt = ieee80211_tdls_mgmt,
02556 };


ros_rt_wmp
Author(s): Danilo Tardioli, dantard@unizar.es
autogenerated on Fri Jan 3 2014 12:07:54