Merge tag 'edac_for_4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
[linux-2.6-block.git] / net / mac80211 / cfg.c
index 5d22eda8a6b1e9d4f8d6f45c1c8c633a892041d3..51622333d4602a60fa39a877d7fbb721ada64bf1 100644 (file)
@@ -158,12 +158,10 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
        if (ret)
                return ret;
 
-       if (type == NL80211_IFTYPE_AP_VLAN &&
-           params && params->use_4addr == 0) {
+       if (type == NL80211_IFTYPE_AP_VLAN && params->use_4addr == 0) {
                RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
                ieee80211_check_fast_rx_iface(sdata);
-       } else if (type == NL80211_IFTYPE_STATION &&
-                  params && params->use_4addr >= 0) {
+       } else if (type == NL80211_IFTYPE_STATION && params->use_4addr >= 0) {
                sdata->u.mgd.use_4addr = params->use_4addr;
        }
 
@@ -792,6 +790,48 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
        return 0;
 }
 
+static int ieee80211_set_ftm_responder_params(
+                               struct ieee80211_sub_if_data *sdata,
+                               const u8 *lci, size_t lci_len,
+                               const u8 *civicloc, size_t civicloc_len)
+{
+       struct ieee80211_ftm_responder_params *new, *old;
+       struct ieee80211_bss_conf *bss_conf;
+       u8 *pos;
+       int len;
+
+       if ((!lci || !lci_len) && (!civicloc || !civicloc_len))
+               return 1;
+
+       bss_conf = &sdata->vif.bss_conf;
+       old = bss_conf->ftmr_params;
+       len = lci_len + civicloc_len;
+
+       new = kzalloc(sizeof(*new) + len, GFP_KERNEL);
+       if (!new)
+               return -ENOMEM;
+
+       pos = (u8 *)(new + 1);
+       if (lci_len) {
+               new->lci_len = lci_len;
+               new->lci = pos;
+               memcpy(pos, lci, lci_len);
+               pos += lci_len;
+       }
+
+       if (civicloc_len) {
+               new->civicloc_len = civicloc_len;
+               new->civicloc = pos;
+               memcpy(pos, civicloc, civicloc_len);
+               pos += civicloc_len;
+       }
+
+       bss_conf->ftmr_params = new;
+       kfree(old);
+
+       return 0;
+}
+
 static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
                                   struct cfg80211_beacon_data *params,
                                   const struct ieee80211_csa_settings *csa)
@@ -865,6 +905,20 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
        if (err == 0)
                changed |= BSS_CHANGED_AP_PROBE_RESP;
 
+       if (params->ftm_responder != -1) {
+               sdata->vif.bss_conf.ftm_responder = params->ftm_responder;
+               err = ieee80211_set_ftm_responder_params(sdata,
+                                                        params->lci,
+                                                        params->lci_len,
+                                                        params->civicloc,
+                                                        params->civicloc_len);
+
+               if (err < 0)
+                       return err;
+
+               changed |= BSS_CHANGED_FTM_RESPONDER;
+       }
+
        rcu_assign_pointer(sdata->u.ap.beacon, new);
 
        if (old)
@@ -911,6 +965,9 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
 
        sdata->vif.bss_conf.beacon_int = params->beacon_interval;
 
+       if (params->he_cap)
+               sdata->vif.bss_conf.he_support = true;
+
        mutex_lock(&local->mtx);
        err = ieee80211_vif_use_channel(sdata, &params->chandef,
                                        IEEE80211_CHANCTX_SHARED);
@@ -1062,6 +1119,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
                kfree_rcu(old_probe_resp, rcu_head);
        sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
 
+       kfree(sdata->vif.bss_conf.ftmr_params);
+       sdata->vif.bss_conf.ftmr_params = NULL;
+
        __sta_info_flush(sdata, true);
        ieee80211_free_keys(sdata, true);
 
@@ -1092,50 +1152,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
        return 0;
 }
 
-/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
-struct iapp_layer2_update {
-       u8 da[ETH_ALEN];        /* broadcast */
-       u8 sa[ETH_ALEN];        /* STA addr */
-       __be16 len;             /* 6 */
-       u8 dsap;                /* 0 */
-       u8 ssap;                /* 0 */
-       u8 control;
-       u8 xid_info[3];
-} __packed;
-
-static void ieee80211_send_layer2_update(struct sta_info *sta)
-{
-       struct iapp_layer2_update *msg;
-       struct sk_buff *skb;
-
-       /* Send Level 2 Update Frame to update forwarding tables in layer 2
-        * bridge devices */
-
-       skb = dev_alloc_skb(sizeof(*msg));
-       if (!skb)
-               return;
-       msg = skb_put(skb, sizeof(*msg));
-
-       /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
-        * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
-
-       eth_broadcast_addr(msg->da);
-       memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
-       msg->len = htons(6);
-       msg->dsap = 0;
-       msg->ssap = 0x01;       /* NULL LSAP, CR Bit: Response */
-       msg->control = 0xaf;    /* XID response lsb.1111F101.
-                                * F=0 (no poll command; unsolicited frame) */
-       msg->xid_info[0] = 0x81;        /* XID format identifier */
-       msg->xid_info[1] = 1;   /* LLC types/classes: Type 1 LLC */
-       msg->xid_info[2] = 0;   /* XID sender's receive window size (RW) */
-
-       skb->dev = sta->sdata->dev;
-       skb->protocol = eth_type_trans(skb, sta->sdata->dev);
-       memset(skb->cb, 0, sizeof(skb->cb));
-       netif_rx_ni(skb);
-}
-
 static int sta_apply_auth_flags(struct ieee80211_local *local,
                                struct sta_info *sta,
                                u32 mask, u32 set)
@@ -1499,7 +1515,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        }
 
        if (layer2_update)
-               ieee80211_send_layer2_update(sta);
+               cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
 
        rcu_read_unlock();
 
@@ -1601,7 +1617,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
                if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
                        ieee80211_vif_inc_num_mcast(sta->sdata);
 
-               ieee80211_send_layer2_update(sta);
+               cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
        }
 
        err = sta_apply_parameters(local, sta, params);
@@ -2918,6 +2934,20 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
                memcpy(pos, beacon->probe_resp, beacon->probe_resp_len);
                pos += beacon->probe_resp_len;
        }
+       if (beacon->ftm_responder)
+               new_beacon->ftm_responder = beacon->ftm_responder;
+       if (beacon->lci) {
+               new_beacon->lci_len = beacon->lci_len;
+               new_beacon->lci = pos;
+               memcpy(pos, beacon->lci, beacon->lci_len);
+               pos += beacon->lci_len;
+       }
+       if (beacon->civicloc) {
+               new_beacon->civicloc_len = beacon->civicloc_len;
+               new_beacon->civicloc = pos;
+               memcpy(pos, beacon->civicloc, beacon->civicloc_len);
+               pos += beacon->civicloc_len;
+       }
 
        return new_beacon;
 }
@@ -3808,6 +3838,17 @@ out:
        return ret;
 }
 
+static int
+ieee80211_get_ftm_responder_stats(struct wiphy *wiphy,
+                                 struct net_device *dev,
+                                 struct cfg80211_ftm_responder_stats *ftm_stats)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       return drv_get_ftm_responder_stats(local, sdata, ftm_stats);
+}
+
 const struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
@@ -3902,4 +3943,5 @@ const struct cfg80211_ops mac80211_config_ops = {
        .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast,
        .tx_control_port = ieee80211_tx_control_port,
        .get_txq_stats = ieee80211_get_txq_stats,
+       .get_ftm_responder_stats = ieee80211_get_ftm_responder_stats,
 };