]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/mac80211/cfg.c
Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next
[karo-tx-linux.git] / net / mac80211 / cfg.c
index 85ac364f4636010128d997ad58fe93fea50e58a4..d197dbeef9ced8de8d212228d18d68abf897792e 100644 (file)
@@ -689,7 +689,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 +1530,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 +1565,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 +1590,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 +2318,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 +2347,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 +2365,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 +2520,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)