]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/mac80211/cfg.c
batman-adv: Prefix packet structs with batadv_
[mirror_ubuntu-artful-kernel.git] / net / mac80211 / cfg.c
index 85ac364f4636010128d997ad58fe93fea50e58a4..c2a2dcbfdf017abc788b58dd3744e3e7a390a18e 100644 (file)
@@ -353,6 +353,7 @@ void sta_set_rate_info_tx(struct sta_info *sta,
 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
+       struct ieee80211_local *local = sdata->local;
        struct timespec uptime;
 
        sinfo->generation = sdata->local->sta_generation;
@@ -388,7 +389,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
        if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
            (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
                sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
-               sinfo->signal = (s8)sta->last_signal;
+               if (!local->ops->get_rssi ||
+                   drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
+                       sinfo->signal = (s8)sta->last_signal;
                sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
        }
 
@@ -517,7 +520,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
         * network device.
         */
 
-       rcu_read_lock();
+       mutex_lock(&local->sta_mtx);
 
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
@@ -546,7 +549,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
                        data[i] = (u8)sinfo.signal_avg;
                i++;
        } else {
-               list_for_each_entry_rcu(sta, &local->sta_list, list) {
+               list_for_each_entry(sta, &local->sta_list, list) {
                        /* Make sure this station belongs to the proper dev */
                        if (sta->sdata->dev != dev)
                                continue;
@@ -603,7 +606,7 @@ do_survey:
        else
                data[i++] = -1LL;
 
-       rcu_read_unlock();
+       mutex_unlock(&local->sta_mtx);
 
        if (WARN_ON(i != STA_STATS_LEN))
                return;
@@ -629,10 +632,11 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
                                 int idx, u8 *mac, struct station_info *sinfo)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
        int ret = -ENOENT;
 
-       rcu_read_lock();
+       mutex_lock(&local->sta_mtx);
 
        sta = sta_info_get_by_idx(sdata, idx);
        if (sta) {
@@ -641,7 +645,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
                sta_set_sinfo(sta, sinfo);
        }
 
-       rcu_read_unlock();
+       mutex_unlock(&local->sta_mtx);
 
        return ret;
 }
@@ -658,10 +662,11 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                                 u8 *mac, struct station_info *sinfo)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
        int ret = -ENOENT;
 
-       rcu_read_lock();
+       mutex_lock(&local->sta_mtx);
 
        sta = sta_info_get_bss(sdata, mac);
        if (sta) {
@@ -669,7 +674,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                sta_set_sinfo(sta, sinfo);
        }
 
-       rcu_read_unlock();
+       mutex_unlock(&local->sta_mtx);
 
        return ret;
 }
@@ -689,7 +694,8 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
        case CHAN_MODE_HOPPING:
                return -EBUSY;
        case CHAN_MODE_FIXED:
-               if (local->oper_channel != chan)
+               if (local->oper_channel != chan ||
+                   (!sdata && local->_oper_channel_type != channel_type))
                        return -EBUSY;
                if (!sdata && local->_oper_channel_type == channel_type)
                        return 0;
@@ -1529,7 +1535,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
        if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
                conf->dot11MeshTTL = nconf->dot11MeshTTL;
        if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
-               conf->dot11MeshTTL = nconf->element_ttl;
+               conf->element_ttl = nconf->element_ttl;
        if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
                conf->auto_open_plinks = nconf->auto_open_plinks;
        if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask))
@@ -1564,17 +1570,16 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
                 * announcements, so require this ifmsh to also be a root node
                 * */
                if (nconf->dot11MeshGateAnnouncementProtocol &&
-                   !conf->dot11MeshHWMPRootMode) {
-                       conf->dot11MeshHWMPRootMode = 1;
+                   !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) {
+                       conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN;
                        ieee80211_mesh_root_setup(ifmsh);
                }
                conf->dot11MeshGateAnnouncementProtocol =
                        nconf->dot11MeshGateAnnouncementProtocol;
        }
-       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) {
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
                conf->dot11MeshHWMPRannInterval =
                        nconf->dot11MeshHWMPRannInterval;
-       }
        if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
                conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
        if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
@@ -1590,6 +1595,15 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
                sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
                ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
        }
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
+               conf->dot11MeshHWMPactivePathToRootTimeout =
+                       nconf->dot11MeshHWMPactivePathToRootTimeout;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
+               conf->dot11MeshHWMProotInterval =
+                       nconf->dot11MeshHWMProotInterval;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
+               conf->dot11MeshHWMPconfirmationInterval =
+                       nconf->dot11MeshHWMPconfirmationInterval;
        return 0;
 }
 
@@ -2309,6 +2323,21 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
 
        mutex_lock(&local->mtx);
        list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
+               struct ieee80211_roc_work *dep, *tmp2;
+
+               list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
+                       if (!mgmt_tx && (unsigned long)dep != cookie)
+                               continue;
+                       else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
+                               continue;
+                       /* found dependent item -- just remove it */
+                       list_del(&dep->list);
+                       mutex_unlock(&local->mtx);
+
+                       ieee80211_roc_notify_destroy(dep);
+                       return 0;
+               }
+
                if (!mgmt_tx && (unsigned long)roc != cookie)
                        continue;
                else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
@@ -2323,6 +2352,13 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
                return -ENOENT;
        }
 
+       /*
+        * We found the item to cancel, so do that. Note that it
+        * may have dependents, which we also cancel (and send
+        * the expired signal for.) Not doing so would be quite
+        * tricky here, but we may need to fix it later.
+        */
+
        if (local->ops->remain_on_channel) {
                if (found->started) {
                        ret = drv_cancel_remain_on_channel(local);
@@ -2334,8 +2370,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
 
                list_del(&found->list);
 
-               ieee80211_run_deferred_scan(local);
-               ieee80211_start_next_roc(local);
+               if (found->started)
+                       ieee80211_start_next_roc(local);
                mutex_unlock(&local->mtx);
 
                ieee80211_roc_notify_destroy(found);
@@ -2489,16 +2525,30 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
                                          u16 frame_type, bool reg)
 {
        struct ieee80211_local *local = wiphy_priv(wiphy);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
-               return;
+       switch (frame_type) {
+       case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
+               if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+                       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
 
-       if (reg)
-               local->probe_req_reg++;
-       else
-               local->probe_req_reg--;
+                       if (reg)
+                               ifibss->auth_frame_registrations++;
+                       else
+                               ifibss->auth_frame_registrations--;
+               }
+               break;
+       case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
+               if (reg)
+                       local->probe_req_reg++;
+               else
+                       local->probe_req_reg--;
 
-       ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+               ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+               break;
+       default:
+               break;
+       }
 }
 
 static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
@@ -2724,9 +2774,8 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
            !sdata->u.mgd.associated)
                return -EINVAL;
 
-#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
-       pr_debug("TDLS mgmt action %d peer %pM\n", action_code, peer);
-#endif
+       tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n",
+                action_code, peer);
 
        skb = dev_alloc_skb(local->hw.extra_tx_headroom +
                            max(sizeof(struct ieee80211_mgmt),
@@ -2835,9 +2884,7 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
                return -EINVAL;
 
-#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
-       pr_debug("TDLS oper %d peer %pM\n", oper, peer);
-#endif
+       tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
 
        switch (oper) {
        case NL80211_TDLS_ENABLE_LINK: