12c8dccc7SJohannes Berg /* 2c5d54fbfSJohannes Berg * Interface handling 30d143fe1SJohannes Berg * 42c8dccc7SJohannes Berg * Copyright 2002-2005, Instant802 Networks, Inc. 52c8dccc7SJohannes Berg * Copyright 2005-2006, Devicescape Software, Inc. 62c8dccc7SJohannes Berg * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> 775636525SJohannes Berg * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 8d98ad83eSJohannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH 9d2941df8SJohannes Berg * Copyright (c) 2016 Intel Deutschland GmbH 102c8dccc7SJohannes Berg * 112c8dccc7SJohannes Berg * This program is free software; you can redistribute it and/or modify 122c8dccc7SJohannes Berg * it under the terms of the GNU General Public License version 2 as 132c8dccc7SJohannes Berg * published by the Free Software Foundation. 142c8dccc7SJohannes Berg */ 155a0e3ad6STejun Heo #include <linux/slab.h> 162c8dccc7SJohannes Berg #include <linux/kernel.h> 172c8dccc7SJohannes Berg #include <linux/if_arp.h> 182c8dccc7SJohannes Berg #include <linux/netdevice.h> 192c8dccc7SJohannes Berg #include <linux/rtnetlink.h> 202c8dccc7SJohannes Berg #include <net/mac80211.h> 21cf0277e7SJohannes Berg #include <net/ieee80211_radiotap.h> 222c8dccc7SJohannes Berg #include "ieee80211_i.h" 232c8dccc7SJohannes Berg #include "sta_info.h" 242c8dccc7SJohannes Berg #include "debugfs_netdev.h" 252c8dccc7SJohannes Berg #include "mesh.h" 260d143fe1SJohannes Berg #include "led.h" 2724487981SJohannes Berg #include "driver-ops.h" 28cf0277e7SJohannes Berg #include "wme.h" 291be7fe8dSBill Jordan #include "rate.h" 302c8dccc7SJohannes Berg 31c771c9d8SJohannes Berg /** 32c771c9d8SJohannes Berg * DOC: Interface list locking 33c771c9d8SJohannes Berg * 34c771c9d8SJohannes Berg * The interface list in each struct ieee80211_local is protected 35c771c9d8SJohannes Berg * three-fold: 36c771c9d8SJohannes Berg * 37c771c9d8SJohannes Berg * (1) modifications may only be done under the RTNL 38c771c9d8SJohannes Berg * (2) modifications and readers are protected against each other by 39c771c9d8SJohannes Berg * the iflist_mtx. 40c771c9d8SJohannes Berg * (3) modifications are done in an RCU manner so atomic readers 41c771c9d8SJohannes Berg * can traverse the list in RCU-safe blocks. 42c771c9d8SJohannes Berg * 43c771c9d8SJohannes Berg * As a consequence, reads (traversals) of the list can be protected 44c771c9d8SJohannes Berg * by either the RTNL, the iflist_mtx or RCU. 45c771c9d8SJohannes Berg */ 46c771c9d8SJohannes Berg 4742bd20d9SAviya Erenfeld static void ieee80211_iface_work(struct work_struct *work); 4842bd20d9SAviya Erenfeld 491ea6f9c0SJohannes Berg bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) 501ea6f9c0SJohannes Berg { 511ea6f9c0SJohannes Berg struct ieee80211_chanctx_conf *chanctx_conf; 521ea6f9c0SJohannes Berg int power; 531ea6f9c0SJohannes Berg 541ea6f9c0SJohannes Berg rcu_read_lock(); 551ea6f9c0SJohannes Berg chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 561ea6f9c0SJohannes Berg if (!chanctx_conf) { 571ea6f9c0SJohannes Berg rcu_read_unlock(); 581ea6f9c0SJohannes Berg return false; 591ea6f9c0SJohannes Berg } 601ea6f9c0SJohannes Berg 610430c883SSimon Wunderlich power = ieee80211_chandef_max_power(&chanctx_conf->def); 621ea6f9c0SJohannes Berg rcu_read_unlock(); 631ea6f9c0SJohannes Berg 641ea6f9c0SJohannes Berg if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL) 651ea6f9c0SJohannes Berg power = min(power, sdata->user_power_level); 661ea6f9c0SJohannes Berg 671ea6f9c0SJohannes Berg if (sdata->ap_power_level != IEEE80211_UNSET_POWER_LEVEL) 681ea6f9c0SJohannes Berg power = min(power, sdata->ap_power_level); 691ea6f9c0SJohannes Berg 701ea6f9c0SJohannes Berg if (power != sdata->vif.bss_conf.txpower) { 711ea6f9c0SJohannes Berg sdata->vif.bss_conf.txpower = power; 721ea6f9c0SJohannes Berg ieee80211_hw_config(sdata->local, 0); 731ea6f9c0SJohannes Berg return true; 741ea6f9c0SJohannes Berg } 751ea6f9c0SJohannes Berg 761ea6f9c0SJohannes Berg return false; 771ea6f9c0SJohannes Berg } 781ea6f9c0SJohannes Berg 79db82d8a9SLorenzo Bianconi void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata, 80db82d8a9SLorenzo Bianconi bool update_bss) 811ea6f9c0SJohannes Berg { 825ad11b50SEmmanuel Grumbach if (__ieee80211_recalc_txpower(sdata) || 835ad11b50SEmmanuel Grumbach (update_bss && ieee80211_sdata_running(sdata))) 841ea6f9c0SJohannes Berg ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); 851ea6f9c0SJohannes Berg } 86c771c9d8SJohannes Berg 8762a40a15SJohannes Berg static u32 __ieee80211_idle_off(struct ieee80211_local *local) 88cc45ae54SJohannes Berg { 89cc45ae54SJohannes Berg if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) 90cc45ae54SJohannes Berg return 0; 91cc45ae54SJohannes Berg 92cc45ae54SJohannes Berg local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; 93cc45ae54SJohannes Berg return IEEE80211_CONF_CHANGE_IDLE; 94cc45ae54SJohannes Berg } 95cc45ae54SJohannes Berg 9662a40a15SJohannes Berg static u32 __ieee80211_idle_on(struct ieee80211_local *local) 97cc45ae54SJohannes Berg { 98cc45ae54SJohannes Berg if (local->hw.conf.flags & IEEE80211_CONF_IDLE) 99cc45ae54SJohannes Berg return 0; 100cc45ae54SJohannes Berg 1013b24f4c6SEmmanuel Grumbach ieee80211_flush_queues(local, NULL, false); 102cc45ae54SJohannes Berg 103cc45ae54SJohannes Berg local->hw.conf.flags |= IEEE80211_CONF_IDLE; 104cc45ae54SJohannes Berg return IEEE80211_CONF_CHANGE_IDLE; 105cc45ae54SJohannes Berg } 106cc45ae54SJohannes Berg 10762a40a15SJohannes Berg static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, 10862a40a15SJohannes Berg bool force_active) 109cc45ae54SJohannes Berg { 1101d5e1266SJohannes Berg bool working, scanning, active; 111cc45ae54SJohannes Berg unsigned int led_trig_start = 0, led_trig_stop = 0; 112cc45ae54SJohannes Berg 113cc45ae54SJohannes Berg lockdep_assert_held(&local->mtx); 114cc45ae54SJohannes Berg 11562a40a15SJohannes Berg active = force_active || 11662a40a15SJohannes Berg !list_empty(&local->chanctx_list) || 11762a40a15SJohannes Berg local->monitors; 118cc45ae54SJohannes Berg 1191d5e1266SJohannes Berg working = !local->ops->remain_on_channel && 1201d5e1266SJohannes Berg !list_empty(&local->roc_list); 121cc45ae54SJohannes Berg 122f1e3e051SJohannes Berg scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || 123f1e3e051SJohannes Berg test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); 124cc45ae54SJohannes Berg 125cc45ae54SJohannes Berg if (working || scanning) 126cc45ae54SJohannes Berg led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; 127cc45ae54SJohannes Berg else 128cc45ae54SJohannes Berg led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; 129cc45ae54SJohannes Berg 130fd0f979aSJohannes Berg if (active) 131cc45ae54SJohannes Berg led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; 132cc45ae54SJohannes Berg else 133cc45ae54SJohannes Berg led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; 134cc45ae54SJohannes Berg 135cc45ae54SJohannes Berg ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); 136cc45ae54SJohannes Berg 137fd0f979aSJohannes Berg if (working || scanning || active) 13862a40a15SJohannes Berg return __ieee80211_idle_off(local); 13962a40a15SJohannes Berg return __ieee80211_idle_on(local); 14062a40a15SJohannes Berg } 14162a40a15SJohannes Berg 14262a40a15SJohannes Berg u32 ieee80211_idle_off(struct ieee80211_local *local) 14362a40a15SJohannes Berg { 14462a40a15SJohannes Berg return __ieee80211_recalc_idle(local, true); 14562a40a15SJohannes Berg } 14662a40a15SJohannes Berg 14762a40a15SJohannes Berg void ieee80211_recalc_idle(struct ieee80211_local *local) 14862a40a15SJohannes Berg { 14962a40a15SJohannes Berg u32 change = __ieee80211_recalc_idle(local, false); 150fd0f979aSJohannes Berg if (change) 151fd0f979aSJohannes Berg ieee80211_hw_config(local, change); 152cc45ae54SJohannes Berg } 153cc45ae54SJohannes Berg 1543899ba90SJohn W. Linville static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr, 15531eba5bcSFelix Fietkau bool check_dup) 156478622e8SHelmut Schaa { 157ac20976dSHelmut Schaa struct ieee80211_local *local = sdata->local; 158ac20976dSHelmut Schaa struct ieee80211_sub_if_data *iter; 159478622e8SHelmut Schaa u64 new, mask, tmp; 160478622e8SHelmut Schaa u8 *m; 161478622e8SHelmut Schaa int ret = 0; 162478622e8SHelmut Schaa 163478622e8SHelmut Schaa if (is_zero_ether_addr(local->hw.wiphy->addr_mask)) 164478622e8SHelmut Schaa return 0; 165478622e8SHelmut Schaa 166478622e8SHelmut Schaa m = addr; 167478622e8SHelmut Schaa new = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | 168478622e8SHelmut Schaa ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | 169478622e8SHelmut Schaa ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); 170478622e8SHelmut Schaa 171478622e8SHelmut Schaa m = local->hw.wiphy->addr_mask; 172478622e8SHelmut Schaa mask = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | 173478622e8SHelmut Schaa ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | 174478622e8SHelmut Schaa ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); 175478622e8SHelmut Schaa 17631eba5bcSFelix Fietkau if (!check_dup) 17731eba5bcSFelix Fietkau return ret; 178478622e8SHelmut Schaa 179478622e8SHelmut Schaa mutex_lock(&local->iflist_mtx); 180ac20976dSHelmut Schaa list_for_each_entry(iter, &local->interfaces, list) { 181ac20976dSHelmut Schaa if (iter == sdata) 182478622e8SHelmut Schaa continue; 183478622e8SHelmut Schaa 1843899ba90SJohn W. Linville if (iter->vif.type == NL80211_IFTYPE_MONITOR && 185d8212184SAviya Erenfeld !(iter->u.mntr.flags & MONITOR_FLAG_ACTIVE)) 186ac20976dSHelmut Schaa continue; 187ac20976dSHelmut Schaa 188ac20976dSHelmut Schaa m = iter->vif.addr; 189478622e8SHelmut Schaa tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | 190478622e8SHelmut Schaa ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | 191478622e8SHelmut Schaa ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); 192478622e8SHelmut Schaa 193478622e8SHelmut Schaa if ((new & ~mask) != (tmp & ~mask)) { 194478622e8SHelmut Schaa ret = -EINVAL; 195478622e8SHelmut Schaa break; 196478622e8SHelmut Schaa } 197478622e8SHelmut Schaa } 198478622e8SHelmut Schaa mutex_unlock(&local->iflist_mtx); 199478622e8SHelmut Schaa 200478622e8SHelmut Schaa return ret; 201478622e8SHelmut Schaa } 202478622e8SHelmut Schaa 20347846c9bSJohannes Berg static int ieee80211_change_mac(struct net_device *dev, void *addr) 20447846c9bSJohannes Berg { 20547846c9bSJohannes Berg struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 206fc5f7577SKalle Valo struct sockaddr *sa = addr; 20731eba5bcSFelix Fietkau bool check_dup = true; 20847846c9bSJohannes Berg int ret; 20947846c9bSJohannes Berg 2109607e6b6SJohannes Berg if (ieee80211_sdata_running(sdata)) 21147846c9bSJohannes Berg return -EBUSY; 21247846c9bSJohannes Berg 21331eba5bcSFelix Fietkau if (sdata->vif.type == NL80211_IFTYPE_MONITOR && 214d8212184SAviya Erenfeld !(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) 21531eba5bcSFelix Fietkau check_dup = false; 21631eba5bcSFelix Fietkau 2173899ba90SJohn W. Linville ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup); 218478622e8SHelmut Schaa if (ret) 219478622e8SHelmut Schaa return ret; 220478622e8SHelmut Schaa 221fc5f7577SKalle Valo ret = eth_mac_addr(dev, sa); 22247846c9bSJohannes Berg 22347846c9bSJohannes Berg if (ret == 0) 224fc5f7577SKalle Valo memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN); 22547846c9bSJohannes Berg 22647846c9bSJohannes Berg return ret; 22747846c9bSJohannes Berg } 22847846c9bSJohannes Berg 2290d143fe1SJohannes Berg static inline int identical_mac_addr_allowed(int type1, int type2) 2300d143fe1SJohannes Berg { 2310d143fe1SJohannes Berg return type1 == NL80211_IFTYPE_MONITOR || 2320d143fe1SJohannes Berg type2 == NL80211_IFTYPE_MONITOR || 233f142c6b9SJohannes Berg type1 == NL80211_IFTYPE_P2P_DEVICE || 234f142c6b9SJohannes Berg type2 == NL80211_IFTYPE_P2P_DEVICE || 2350d143fe1SJohannes Berg (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_WDS) || 2360d143fe1SJohannes Berg (type1 == NL80211_IFTYPE_WDS && 2370d143fe1SJohannes Berg (type2 == NL80211_IFTYPE_WDS || 2380d143fe1SJohannes Berg type2 == NL80211_IFTYPE_AP)) || 2390d143fe1SJohannes Berg (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_AP_VLAN) || 2400d143fe1SJohannes Berg (type1 == NL80211_IFTYPE_AP_VLAN && 2410d143fe1SJohannes Berg (type2 == NL80211_IFTYPE_AP || 2420d143fe1SJohannes Berg type2 == NL80211_IFTYPE_AP_VLAN)); 2430d143fe1SJohannes Berg } 2440d143fe1SJohannes Berg 24587490f6dSJohannes Berg static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, 24687490f6dSJohannes Berg enum nl80211_iftype iftype) 2470d143fe1SJohannes Berg { 248b4a4bf5dSJohannes Berg struct ieee80211_local *local = sdata->local; 24987490f6dSJohannes Berg struct ieee80211_sub_if_data *nsdata; 250b6a55015SLuciano Coelho int ret; 2510d143fe1SJohannes Berg 25287490f6dSJohannes Berg ASSERT_RTNL(); 2530d143fe1SJohannes Berg 2540d143fe1SJohannes Berg /* we hold the RTNL here so can safely walk the list */ 2550d143fe1SJohannes Berg list_for_each_entry(nsdata, &local->interfaces, list) { 256371a255eSJohannes Berg if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { 2570d143fe1SJohannes Berg /* 258239281f8SRostislav Lisovy * Only OCB and monitor mode may coexist 259239281f8SRostislav Lisovy */ 260239281f8SRostislav Lisovy if ((sdata->vif.type == NL80211_IFTYPE_OCB && 261239281f8SRostislav Lisovy nsdata->vif.type != NL80211_IFTYPE_MONITOR) || 262239281f8SRostislav Lisovy (sdata->vif.type != NL80211_IFTYPE_MONITOR && 263239281f8SRostislav Lisovy nsdata->vif.type == NL80211_IFTYPE_OCB)) 264239281f8SRostislav Lisovy return -EBUSY; 265239281f8SRostislav Lisovy 266239281f8SRostislav Lisovy /* 2670d143fe1SJohannes Berg * Allow only a single IBSS interface to be up at any 2680d143fe1SJohannes Berg * time. This is restricted because beacon distribution 2690d143fe1SJohannes Berg * cannot work properly if both are in the same IBSS. 2700d143fe1SJohannes Berg * 2710d143fe1SJohannes Berg * To remove this restriction we'd have to disallow them 2720d143fe1SJohannes Berg * from setting the same SSID on different IBSS interfaces 2730d143fe1SJohannes Berg * belonging to the same hardware. Then, however, we're 2740d143fe1SJohannes Berg * faced with having to adopt two different TSF timers... 2750d143fe1SJohannes Berg */ 27687490f6dSJohannes Berg if (iftype == NL80211_IFTYPE_ADHOC && 2770d143fe1SJohannes Berg nsdata->vif.type == NL80211_IFTYPE_ADHOC) 2780d143fe1SJohannes Berg return -EBUSY; 27973da7d5bSSimon Wunderlich /* 28073da7d5bSSimon Wunderlich * will not add another interface while any channel 28173da7d5bSSimon Wunderlich * switch is active. 28273da7d5bSSimon Wunderlich */ 28373da7d5bSSimon Wunderlich if (nsdata->vif.csa_active) 28473da7d5bSSimon Wunderlich return -EBUSY; 2850d143fe1SJohannes Berg 2860d143fe1SJohannes Berg /* 2870d143fe1SJohannes Berg * The remaining checks are only performed for interfaces 2880d143fe1SJohannes Berg * with the same MAC address. 2890d143fe1SJohannes Berg */ 290371a255eSJohannes Berg if (!ether_addr_equal(sdata->vif.addr, 291371a255eSJohannes Berg nsdata->vif.addr)) 2920d143fe1SJohannes Berg continue; 2930d143fe1SJohannes Berg 2940d143fe1SJohannes Berg /* 2950d143fe1SJohannes Berg * check whether it may have the same address 2960d143fe1SJohannes Berg */ 29787490f6dSJohannes Berg if (!identical_mac_addr_allowed(iftype, 2980d143fe1SJohannes Berg nsdata->vif.type)) 2990d143fe1SJohannes Berg return -ENOTUNIQ; 3000d143fe1SJohannes Berg 3010d143fe1SJohannes Berg /* 3020d143fe1SJohannes Berg * can only add VLANs to enabled APs 3030d143fe1SJohannes Berg */ 30487490f6dSJohannes Berg if (iftype == NL80211_IFTYPE_AP_VLAN && 3050d143fe1SJohannes Berg nsdata->vif.type == NL80211_IFTYPE_AP) 3060d143fe1SJohannes Berg sdata->bss = &nsdata->u.ap; 3070d143fe1SJohannes Berg } 3080d143fe1SJohannes Berg } 3090d143fe1SJohannes Berg 310b6a55015SLuciano Coelho mutex_lock(&local->chanctx_mtx); 311b6a55015SLuciano Coelho ret = ieee80211_check_combinations(sdata, NULL, 0, 0); 312b6a55015SLuciano Coelho mutex_unlock(&local->chanctx_mtx); 313b6a55015SLuciano Coelho return ret; 31487490f6dSJohannes Berg } 31587490f6dSJohannes Berg 316a9865538SJohannes Berg static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata, 317a9865538SJohannes Berg enum nl80211_iftype iftype) 3183a25a8c8SJohannes Berg { 3193a25a8c8SJohannes Berg int n_queues = sdata->local->hw.queues; 3203a25a8c8SJohannes Berg int i; 3213a25a8c8SJohannes Berg 322708d50edSAyala Beker if (iftype == NL80211_IFTYPE_NAN) 323708d50edSAyala Beker return 0; 324708d50edSAyala Beker 325a9865538SJohannes Berg if (iftype != NL80211_IFTYPE_P2P_DEVICE) { 3263a25a8c8SJohannes Berg for (i = 0; i < IEEE80211_NUM_ACS; i++) { 3273a25a8c8SJohannes Berg if (WARN_ON_ONCE(sdata->vif.hw_queue[i] == 3283a25a8c8SJohannes Berg IEEE80211_INVAL_HW_QUEUE)) 3293a25a8c8SJohannes Berg return -EINVAL; 3303a25a8c8SJohannes Berg if (WARN_ON_ONCE(sdata->vif.hw_queue[i] >= 3313a25a8c8SJohannes Berg n_queues)) 3323a25a8c8SJohannes Berg return -EINVAL; 3333a25a8c8SJohannes Berg } 3340ef24e52SIlan Peer } 3353a25a8c8SJohannes Berg 336a9865538SJohannes Berg if ((iftype != NL80211_IFTYPE_AP && 337a9865538SJohannes Berg iftype != NL80211_IFTYPE_P2P_GO && 338a9865538SJohannes Berg iftype != NL80211_IFTYPE_MESH_POINT) || 33930686bf7SJohannes Berg !ieee80211_hw_check(&sdata->local->hw, QUEUE_CONTROL)) { 3403a25a8c8SJohannes Berg sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; 3413a25a8c8SJohannes Berg return 0; 3423a25a8c8SJohannes Berg } 3433a25a8c8SJohannes Berg 3443a25a8c8SJohannes Berg if (WARN_ON_ONCE(sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE)) 3453a25a8c8SJohannes Berg return -EINVAL; 3463a25a8c8SJohannes Berg 3473a25a8c8SJohannes Berg if (WARN_ON_ONCE(sdata->vif.cab_queue >= n_queues)) 3483a25a8c8SJohannes Berg return -EINVAL; 3493a25a8c8SJohannes Berg 3503a25a8c8SJohannes Berg return 0; 3513a25a8c8SJohannes Berg } 3523a25a8c8SJohannes Berg 35385416a4fSChristian Lamparter void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, 35485416a4fSChristian Lamparter const int offset) 35585416a4fSChristian Lamparter { 35685416a4fSChristian Lamparter struct ieee80211_local *local = sdata->local; 357d8212184SAviya Erenfeld u32 flags = sdata->u.mntr.flags; 35885416a4fSChristian Lamparter 35985416a4fSChristian Lamparter #define ADJUST(_f, _s) do { \ 36085416a4fSChristian Lamparter if (flags & MONITOR_FLAG_##_f) \ 36185416a4fSChristian Lamparter local->fif_##_s += offset; \ 36285416a4fSChristian Lamparter } while (0) 36385416a4fSChristian Lamparter 36485416a4fSChristian Lamparter ADJUST(FCSFAIL, fcsfail); 36585416a4fSChristian Lamparter ADJUST(PLCPFAIL, plcpfail); 36685416a4fSChristian Lamparter ADJUST(CONTROL, control); 36785416a4fSChristian Lamparter ADJUST(CONTROL, pspoll); 36885416a4fSChristian Lamparter ADJUST(OTHER_BSS, other_bss); 36985416a4fSChristian Lamparter 37085416a4fSChristian Lamparter #undef ADJUST 37185416a4fSChristian Lamparter } 37285416a4fSChristian Lamparter 3733a25a8c8SJohannes Berg static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) 3743a25a8c8SJohannes Berg { 3753a25a8c8SJohannes Berg struct ieee80211_local *local = sdata->local; 3763a25a8c8SJohannes Berg int i; 3773a25a8c8SJohannes Berg 3783a25a8c8SJohannes Berg for (i = 0; i < IEEE80211_NUM_ACS; i++) { 37930686bf7SJohannes Berg if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) 3803a25a8c8SJohannes Berg sdata->vif.hw_queue[i] = IEEE80211_INVAL_HW_QUEUE; 381a9d3c05cSJohannes Berg else if (local->hw.queues >= IEEE80211_NUM_ACS) 3823a25a8c8SJohannes Berg sdata->vif.hw_queue[i] = i; 383a9d3c05cSJohannes Berg else 384a9d3c05cSJohannes Berg sdata->vif.hw_queue[i] = 0; 3853a25a8c8SJohannes Berg } 3863a25a8c8SJohannes Berg sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; 3873a25a8c8SJohannes Berg } 3883a25a8c8SJohannes Berg 3893c3e21e7SJohannes Berg int ieee80211_add_virtual_monitor(struct ieee80211_local *local) 3904b6f1dd6SJohannes Berg { 3914b6f1dd6SJohannes Berg struct ieee80211_sub_if_data *sdata; 3928b305780SJohannes Berg int ret; 3934b6f1dd6SJohannes Berg 39430686bf7SJohannes Berg if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) 3954b6f1dd6SJohannes Berg return 0; 3964b6f1dd6SJohannes Berg 3978b305780SJohannes Berg ASSERT_RTNL(); 398685fb72bSJohannes Berg 3994b6f1dd6SJohannes Berg if (local->monitor_sdata) 4008b305780SJohannes Berg return 0; 4014b6f1dd6SJohannes Berg 4024b6f1dd6SJohannes Berg sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); 4038b305780SJohannes Berg if (!sdata) 4048b305780SJohannes Berg return -ENOMEM; 4054b6f1dd6SJohannes Berg 4064b6f1dd6SJohannes Berg /* set up data */ 4074b6f1dd6SJohannes Berg sdata->local = local; 4084b6f1dd6SJohannes Berg sdata->vif.type = NL80211_IFTYPE_MONITOR; 4094b6f1dd6SJohannes Berg snprintf(sdata->name, IFNAMSIZ, "%s-monitor", 4104b6f1dd6SJohannes Berg wiphy_name(local->hw.wiphy)); 41134171dc0SEmmanuel Grumbach sdata->wdev.iftype = NL80211_IFTYPE_MONITOR; 4124b6f1dd6SJohannes Berg 4132475b1ccSMax Stepanov sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 4142475b1ccSMax Stepanov 4153a25a8c8SJohannes Berg ieee80211_set_default_queues(sdata); 4163a25a8c8SJohannes Berg 4174b6f1dd6SJohannes Berg ret = drv_add_interface(local, sdata); 4184b6f1dd6SJohannes Berg if (WARN_ON(ret)) { 4194b6f1dd6SJohannes Berg /* ok .. stupid driver, it asked for this! */ 4204b6f1dd6SJohannes Berg kfree(sdata); 4218b305780SJohannes Berg return ret; 4224b6f1dd6SJohannes Berg } 4234b6f1dd6SJohannes Berg 424a9865538SJohannes Berg ret = ieee80211_check_queues(sdata, NL80211_IFTYPE_MONITOR); 4253a25a8c8SJohannes Berg if (ret) { 4263a25a8c8SJohannes Berg kfree(sdata); 4278b305780SJohannes Berg return ret; 4283a25a8c8SJohannes Berg } 4293a25a8c8SJohannes Berg 430fab57a6cSJohannes Berg mutex_lock(&local->iflist_mtx); 431fab57a6cSJohannes Berg rcu_assign_pointer(local->monitor_sdata, sdata); 432fab57a6cSJohannes Berg mutex_unlock(&local->iflist_mtx); 433fab57a6cSJohannes Berg 43434a3740dSJohannes Berg mutex_lock(&local->mtx); 4354bf88530SJohannes Berg ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, 43655de908aSJohannes Berg IEEE80211_CHANCTX_EXCLUSIVE); 43734a3740dSJohannes Berg mutex_unlock(&local->mtx); 43855de908aSJohannes Berg if (ret) { 439fab57a6cSJohannes Berg mutex_lock(&local->iflist_mtx); 4400c2bef46SMonam Agarwal RCU_INIT_POINTER(local->monitor_sdata, NULL); 441fab57a6cSJohannes Berg mutex_unlock(&local->iflist_mtx); 442fab57a6cSJohannes Berg synchronize_net(); 44355de908aSJohannes Berg drv_remove_interface(local, sdata); 44455de908aSJohannes Berg kfree(sdata); 4458b305780SJohannes Berg return ret; 44655de908aSJohannes Berg } 44755de908aSJohannes Berg 44842bd20d9SAviya Erenfeld skb_queue_head_init(&sdata->skb_queue); 44942bd20d9SAviya Erenfeld INIT_WORK(&sdata->work, ieee80211_iface_work); 45042bd20d9SAviya Erenfeld 4518b305780SJohannes Berg return 0; 4524b6f1dd6SJohannes Berg } 4534b6f1dd6SJohannes Berg 4543c3e21e7SJohannes Berg void ieee80211_del_virtual_monitor(struct ieee80211_local *local) 4554b6f1dd6SJohannes Berg { 4564b6f1dd6SJohannes Berg struct ieee80211_sub_if_data *sdata; 4574b6f1dd6SJohannes Berg 45830686bf7SJohannes Berg if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) 4594b6f1dd6SJohannes Berg return; 4604b6f1dd6SJohannes Berg 4618b305780SJohannes Berg ASSERT_RTNL(); 4628b305780SJohannes Berg 463685fb72bSJohannes Berg mutex_lock(&local->iflist_mtx); 4644b6f1dd6SJohannes Berg 465685fb72bSJohannes Berg sdata = rcu_dereference_protected(local->monitor_sdata, 466685fb72bSJohannes Berg lockdep_is_held(&local->iflist_mtx)); 4678b305780SJohannes Berg if (!sdata) { 4688b305780SJohannes Berg mutex_unlock(&local->iflist_mtx); 4698b305780SJohannes Berg return; 4708b305780SJohannes Berg } 4714b6f1dd6SJohannes Berg 4720c2bef46SMonam Agarwal RCU_INIT_POINTER(local->monitor_sdata, NULL); 4738b305780SJohannes Berg mutex_unlock(&local->iflist_mtx); 4748b305780SJohannes Berg 4754b6f1dd6SJohannes Berg synchronize_net(); 4764b6f1dd6SJohannes Berg 47734a3740dSJohannes Berg mutex_lock(&local->mtx); 47855de908aSJohannes Berg ieee80211_vif_release_channel(sdata); 47934a3740dSJohannes Berg mutex_unlock(&local->mtx); 48055de908aSJohannes Berg 4814b6f1dd6SJohannes Berg drv_remove_interface(local, sdata); 4824b6f1dd6SJohannes Berg 4834b6f1dd6SJohannes Berg kfree(sdata); 4844b6f1dd6SJohannes Berg } 4854b6f1dd6SJohannes Berg 48634d4bc4dSJohannes Berg /* 48734d4bc4dSJohannes Berg * NOTE: Be very careful when changing this function, it must NOT return 48834d4bc4dSJohannes Berg * an error on interface type changes that have been pre-checked, so most 48934d4bc4dSJohannes Berg * checks should be in ieee80211_check_concurrent_iface. 49034d4bc4dSJohannes Berg */ 491f142c6b9SJohannes Berg int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) 49287490f6dSJohannes Berg { 493f142c6b9SJohannes Berg struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 494f142c6b9SJohannes Berg struct net_device *dev = wdev->netdev; 49587490f6dSJohannes Berg struct ieee80211_local *local = sdata->local; 49687490f6dSJohannes Berg struct sta_info *sta; 49787490f6dSJohannes Berg u32 changed = 0; 49887490f6dSJohannes Berg int res; 49987490f6dSJohannes Berg u32 hw_reconf_flags = 0; 50087490f6dSJohannes Berg 5010d143fe1SJohannes Berg switch (sdata->vif.type) { 5020d143fe1SJohannes Berg case NL80211_IFTYPE_WDS: 5030d143fe1SJohannes Berg if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) 5040d143fe1SJohannes Berg return -ENOLINK; 5050d143fe1SJohannes Berg break; 506665c93a9SJohannes Berg case NL80211_IFTYPE_AP_VLAN: { 507665c93a9SJohannes Berg struct ieee80211_sub_if_data *master; 508665c93a9SJohannes Berg 5090d143fe1SJohannes Berg if (!sdata->bss) 5100d143fe1SJohannes Berg return -ENOLINK; 511665c93a9SJohannes Berg 5124e141dadSMichal Kazior mutex_lock(&local->mtx); 5130d143fe1SJohannes Berg list_add(&sdata->u.vlan.list, &sdata->bss->vlans); 5144e141dadSMichal Kazior mutex_unlock(&local->mtx); 515665c93a9SJohannes Berg 516665c93a9SJohannes Berg master = container_of(sdata->bss, 517665c93a9SJohannes Berg struct ieee80211_sub_if_data, u.ap); 518665c93a9SJohannes Berg sdata->control_port_protocol = 519665c93a9SJohannes Berg master->control_port_protocol; 520665c93a9SJohannes Berg sdata->control_port_no_encrypt = 521665c93a9SJohannes Berg master->control_port_no_encrypt; 5221351c5d3SJohannes Berg sdata->vif.cab_queue = master->vif.cab_queue; 5231351c5d3SJohannes Berg memcpy(sdata->vif.hw_queue, master->vif.hw_queue, 5241351c5d3SJohannes Berg sizeof(sdata->vif.hw_queue)); 5252967e031SFelix Fietkau sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef; 526f9dca80bSMichal Kazior 527f9dca80bSMichal Kazior mutex_lock(&local->key_mtx); 528f9dca80bSMichal Kazior sdata->crypto_tx_tailroom_needed_cnt += 529f9dca80bSMichal Kazior master->crypto_tx_tailroom_needed_cnt; 530f9dca80bSMichal Kazior mutex_unlock(&local->key_mtx); 531f9dca80bSMichal Kazior 5320d143fe1SJohannes Berg break; 533665c93a9SJohannes Berg } 5340d143fe1SJohannes Berg case NL80211_IFTYPE_AP: 5350d143fe1SJohannes Berg sdata->bss = &sdata->u.ap; 5360d143fe1SJohannes Berg break; 5370d143fe1SJohannes Berg case NL80211_IFTYPE_MESH_POINT: 5380d143fe1SJohannes Berg case NL80211_IFTYPE_STATION: 5390d143fe1SJohannes Berg case NL80211_IFTYPE_MONITOR: 5400d143fe1SJohannes Berg case NL80211_IFTYPE_ADHOC: 541f142c6b9SJohannes Berg case NL80211_IFTYPE_P2P_DEVICE: 5426e0bd6c3SRostislav Lisovy case NL80211_IFTYPE_OCB: 543cb3b7d87SAyala Beker case NL80211_IFTYPE_NAN: 5440d143fe1SJohannes Berg /* no special treatment */ 5450d143fe1SJohannes Berg break; 5460d143fe1SJohannes Berg case NL80211_IFTYPE_UNSPECIFIED: 5472e161f78SJohannes Berg case NUM_NL80211_IFTYPES: 5482ca27bcfSJohannes Berg case NL80211_IFTYPE_P2P_CLIENT: 5492ca27bcfSJohannes Berg case NL80211_IFTYPE_P2P_GO: 5500d143fe1SJohannes Berg /* cannot happen */ 5510d143fe1SJohannes Berg WARN_ON(1); 5520d143fe1SJohannes Berg break; 5530d143fe1SJohannes Berg } 5540d143fe1SJohannes Berg 5550d143fe1SJohannes Berg if (local->open_count == 0) { 55624487981SJohannes Berg res = drv_start(local); 5570d143fe1SJohannes Berg if (res) 5580d143fe1SJohannes Berg goto err_del_bss; 559e8975581SJohannes Berg /* we're brought up, everything changes */ 560e8975581SJohannes Berg hw_reconf_flags = ~0; 5611f87f7d3SJohannes Berg ieee80211_led_radio(local, true); 56267408c8cSJohannes Berg ieee80211_mod_tpt_led_trig(local, 56367408c8cSJohannes Berg IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); 5640d143fe1SJohannes Berg } 5650d143fe1SJohannes Berg 5660d143fe1SJohannes Berg /* 567bf533e0bSJohannes Berg * Copy the hopefully now-present MAC address to 568bf533e0bSJohannes Berg * this interface, if it has the special null one. 5690d143fe1SJohannes Berg */ 570f142c6b9SJohannes Berg if (dev && is_zero_ether_addr(dev->dev_addr)) { 571bf533e0bSJohannes Berg memcpy(dev->dev_addr, 5720d143fe1SJohannes Berg local->hw.wiphy->perm_addr, 5730d143fe1SJohannes Berg ETH_ALEN); 574bf533e0bSJohannes Berg memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); 5750d143fe1SJohannes Berg 5760d143fe1SJohannes Berg if (!is_valid_ether_addr(dev->dev_addr)) { 5774d6c36faSJohannes Berg res = -EADDRNOTAVAIL; 5784d6c36faSJohannes Berg goto err_stop; 5790d143fe1SJohannes Berg } 580bf533e0bSJohannes Berg } 5810d143fe1SJohannes Berg 5820d143fe1SJohannes Berg switch (sdata->vif.type) { 5830d143fe1SJohannes Berg case NL80211_IFTYPE_AP_VLAN: 5844d76d21bSJohannes Berg /* no need to tell driver, but set carrier and chanctx */ 5854d76d21bSJohannes Berg if (rtnl_dereference(sdata->bss->beacon)) { 5864d76d21bSJohannes Berg ieee80211_vif_vlan_copy_chanctx(sdata); 5873edaf3e6SJohannes Berg netif_carrier_on(dev); 5884d76d21bSJohannes Berg } else { 5893edaf3e6SJohannes Berg netif_carrier_off(dev); 5904d76d21bSJohannes Berg } 5910d143fe1SJohannes Berg break; 5920d143fe1SJohannes Berg case NL80211_IFTYPE_MONITOR: 593d8212184SAviya Erenfeld if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) { 5940d143fe1SJohannes Berg local->cooked_mntrs++; 5950d143fe1SJohannes Berg break; 5960d143fe1SJohannes Berg } 5970d143fe1SJohannes Berg 598d8212184SAviya Erenfeld if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) { 59931eba5bcSFelix Fietkau res = drv_add_interface(local, sdata); 60031eba5bcSFelix Fietkau if (res) 60131eba5bcSFelix Fietkau goto err_stop; 60231eba5bcSFelix Fietkau } else if (local->monitors == 0 && local->open_count == 0) { 603075e0847SJohannes Berg res = ieee80211_add_virtual_monitor(local); 604075e0847SJohannes Berg if (res) 605075e0847SJohannes Berg goto err_stop; 606075e0847SJohannes Berg } 607075e0847SJohannes Berg 6080d143fe1SJohannes Berg /* must be before the call to ieee80211_configure_filter */ 6090d143fe1SJohannes Berg local->monitors++; 610e8975581SJohannes Berg if (local->monitors == 1) { 6110869aea0SJohannes Berg local->hw.conf.flags |= IEEE80211_CONF_MONITOR; 6120869aea0SJohannes Berg hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 613e8975581SJohannes Berg } 6140d143fe1SJohannes Berg 61585416a4fSChristian Lamparter ieee80211_adjust_monitor_flags(sdata, 1); 6160d143fe1SJohannes Berg ieee80211_configure_filter(local); 617801d929cSFelix Fietkau mutex_lock(&local->mtx); 618801d929cSFelix Fietkau ieee80211_recalc_idle(local); 619801d929cSFelix Fietkau mutex_unlock(&local->mtx); 62053e9b1deSDavid Gnedt 62153e9b1deSDavid Gnedt netif_carrier_on(dev); 6220d143fe1SJohannes Berg break; 6230d143fe1SJohannes Berg default: 62434d4bc4dSJohannes Berg if (coming_up) { 625075e0847SJohannes Berg ieee80211_del_virtual_monitor(local); 626075e0847SJohannes Berg 6277b7eab6fSJohannes Berg res = drv_add_interface(local, sdata); 6280d143fe1SJohannes Berg if (res) 6290d143fe1SJohannes Berg goto err_stop; 630a9865538SJohannes Berg res = ieee80211_check_queues(sdata, 631a9865538SJohannes Berg ieee80211_vif_type_p2p(&sdata->vif)); 6323a25a8c8SJohannes Berg if (res) 6333a25a8c8SJohannes Berg goto err_del_interface; 63434d4bc4dSJohannes Berg } 6350d143fe1SJohannes Berg 63629cbe68cSJohannes Berg if (sdata->vif.type == NL80211_IFTYPE_AP) { 637e3b90ca2SIgor Perminov local->fif_pspoll++; 6387be5086dSJohannes Berg local->fif_probe_req++; 639e3b90ca2SIgor Perminov 640e3b90ca2SIgor Perminov ieee80211_configure_filter(local); 6417be5086dSJohannes Berg } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 6427be5086dSJohannes Berg local->fif_probe_req++; 643a3c9aa51SAndrey Yurovsky } 644e3b90ca2SIgor Perminov 645708d50edSAyala Beker if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 646708d50edSAyala Beker sdata->vif.type != NL80211_IFTYPE_NAN) 6470d143fe1SJohannes Berg changed |= ieee80211_reset_erp_info(sdata); 6480d143fe1SJohannes Berg ieee80211_bss_info_change_notify(sdata, changed); 6490d143fe1SJohannes Berg 650c405c629SJohannes Berg switch (sdata->vif.type) { 651c405c629SJohannes Berg case NL80211_IFTYPE_STATION: 652c405c629SJohannes Berg case NL80211_IFTYPE_ADHOC: 653c405c629SJohannes Berg case NL80211_IFTYPE_AP: 654c405c629SJohannes Berg case NL80211_IFTYPE_MESH_POINT: 6556e0bd6c3SRostislav Lisovy case NL80211_IFTYPE_OCB: 6560d143fe1SJohannes Berg netif_carrier_off(dev); 657c405c629SJohannes Berg break; 6581411af15SJohannes Berg case NL80211_IFTYPE_WDS: 659f142c6b9SJohannes Berg case NL80211_IFTYPE_P2P_DEVICE: 660cb3b7d87SAyala Beker case NL80211_IFTYPE_NAN: 6611411af15SJohannes Berg break; 662c405c629SJohannes Berg default: 663a2310824SJohannes Berg /* not reached */ 664a2310824SJohannes Berg WARN_ON(1); 665c405c629SJohannes Berg } 66659034591SEliad Peller 66759034591SEliad Peller /* 668cec66283SJohannes Berg * Set default queue parameters so drivers don't 66959034591SEliad Peller * need to initialise the hardware if the hardware 670cec66283SJohannes Berg * doesn't start up with sane defaults. 671cec66283SJohannes Berg * Enable QoS for anything but station interfaces. 67259034591SEliad Peller */ 673cec66283SJohannes Berg ieee80211_set_wmm_default(sdata, true, 674cec66283SJohannes Berg sdata->vif.type != NL80211_IFTYPE_STATION); 6750d143fe1SJohannes Berg } 6760d143fe1SJohannes Berg 6772d2080c3SJohannes Berg set_bit(SDATA_STATE_RUNNING, &sdata->state); 6782d2080c3SJohannes Berg 679f64331d5SJohannes Berg switch (sdata->vif.type) { 680f64331d5SJohannes Berg case NL80211_IFTYPE_WDS: 6810d143fe1SJohannes Berg /* Create STA entry for the WDS peer */ 6820d143fe1SJohannes Berg sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, 6830d143fe1SJohannes Berg GFP_KERNEL); 6840d143fe1SJohannes Berg if (!sta) { 6850d143fe1SJohannes Berg res = -ENOMEM; 6860d143fe1SJohannes Berg goto err_del_interface; 6870d143fe1SJohannes Berg } 6880d143fe1SJohannes Berg 68983d5cc01SJohannes Berg sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 69083d5cc01SJohannes Berg sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); 69183d5cc01SJohannes Berg sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); 6920d143fe1SJohannes Berg 6930d143fe1SJohannes Berg res = sta_info_insert(sta); 6940d143fe1SJohannes Berg if (res) { 6950d143fe1SJohannes Berg /* STA has been freed */ 6960d143fe1SJohannes Berg goto err_del_interface; 6970d143fe1SJohannes Berg } 6981be7fe8dSBill Jordan 6991be7fe8dSBill Jordan rate_control_rate_init(sta); 7001411af15SJohannes Berg netif_carrier_on(dev); 701f64331d5SJohannes Berg break; 702f64331d5SJohannes Berg case NL80211_IFTYPE_P2P_DEVICE: 703f142c6b9SJohannes Berg rcu_assign_pointer(local->p2p_sdata, sdata); 704f64331d5SJohannes Berg break; 705f64331d5SJohannes Berg case NL80211_IFTYPE_MONITOR: 706f64331d5SJohannes Berg if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) 707f64331d5SJohannes Berg break; 708f64331d5SJohannes Berg list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list); 709f64331d5SJohannes Berg break; 710f64331d5SJohannes Berg default: 711f64331d5SJohannes Berg break; 7120d143fe1SJohannes Berg } 7130d143fe1SJohannes Berg 7140d143fe1SJohannes Berg /* 7150d143fe1SJohannes Berg * set_multicast_list will be invoked by the networking core 7160d143fe1SJohannes Berg * which will check whether any increments here were done in 7170d143fe1SJohannes Berg * error and sync them down to the hardware as filter flags. 7180d143fe1SJohannes Berg */ 7190d143fe1SJohannes Berg if (sdata->flags & IEEE80211_SDATA_ALLMULTI) 7200d143fe1SJohannes Berg atomic_inc(&local->iff_allmultis); 7210d143fe1SJohannes Berg 72234d4bc4dSJohannes Berg if (coming_up) 7230d143fe1SJohannes Berg local->open_count++; 72434d4bc4dSJohannes Berg 72559034591SEliad Peller if (hw_reconf_flags) 726e8975581SJohannes Berg ieee80211_hw_config(local, hw_reconf_flags); 7270d143fe1SJohannes Berg 7284a733ef1SJohannes Berg ieee80211_recalc_ps(local); 729965bedadSJohannes Berg 7302b436312SJohannes Berg if (sdata->vif.type == NL80211_IFTYPE_MONITOR || 7317d65f829SJohannes Berg sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 7327d65f829SJohannes Berg local->ops->wake_tx_queue) { 7332b436312SJohannes Berg /* XXX: for AP_VLAN, actually track AP queues */ 7342b436312SJohannes Berg netif_tx_start_all_queues(dev); 7352b436312SJohannes Berg } else if (dev) { 7362b730daaSJohannes Berg unsigned long flags; 7372b730daaSJohannes Berg int n_acs = IEEE80211_NUM_ACS; 7382b730daaSJohannes Berg int ac; 7392b730daaSJohannes Berg 7402b730daaSJohannes Berg if (local->hw.queues < IEEE80211_NUM_ACS) 7412b730daaSJohannes Berg n_acs = 1; 7422b730daaSJohannes Berg 7432b730daaSJohannes Berg spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 7442b730daaSJohannes Berg if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE || 7452b730daaSJohannes Berg (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 && 7462b730daaSJohannes Berg skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) { 7472b730daaSJohannes Berg for (ac = 0; ac < n_acs; ac++) { 7482b730daaSJohannes Berg int ac_queue = sdata->vif.hw_queue[ac]; 7492b730daaSJohannes Berg 7502b730daaSJohannes Berg if (local->queue_stop_reasons[ac_queue] == 0 && 7512b730daaSJohannes Berg skb_queue_empty(&local->pending[ac_queue])) 7522b730daaSJohannes Berg netif_start_subqueue(dev, ac); 7532b730daaSJohannes Berg } 7542b730daaSJohannes Berg } 7552b730daaSJohannes Berg spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 7562b730daaSJohannes Berg } 7570d143fe1SJohannes Berg 7580d143fe1SJohannes Berg return 0; 7590d143fe1SJohannes Berg err_del_interface: 7607b7eab6fSJohannes Berg drv_remove_interface(local, sdata); 7610d143fe1SJohannes Berg err_stop: 76224487981SJohannes Berg if (!local->open_count) 76324487981SJohannes Berg drv_stop(local); 7640d143fe1SJohannes Berg err_del_bss: 7650d143fe1SJohannes Berg sdata->bss = NULL; 7664e141dadSMichal Kazior if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 7674e141dadSMichal Kazior mutex_lock(&local->mtx); 7680d143fe1SJohannes Berg list_del(&sdata->u.vlan.list); 7694e141dadSMichal Kazior mutex_unlock(&local->mtx); 7704e141dadSMichal Kazior } 7714d6c36faSJohannes Berg /* might already be clear but that doesn't matter */ 7722d2080c3SJohannes Berg clear_bit(SDATA_STATE_RUNNING, &sdata->state); 7730d143fe1SJohannes Berg return res; 7740d143fe1SJohannes Berg } 7750d143fe1SJohannes Berg 77634d4bc4dSJohannes Berg static int ieee80211_open(struct net_device *dev) 7770d143fe1SJohannes Berg { 7780d143fe1SJohannes Berg struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 77934d4bc4dSJohannes Berg int err; 78034d4bc4dSJohannes Berg 78134d4bc4dSJohannes Berg /* fail early if user set an invalid address */ 7822fcf2824SMohammed Shafi Shajakhan if (!is_valid_ether_addr(dev->dev_addr)) 78334d4bc4dSJohannes Berg return -EADDRNOTAVAIL; 78434d4bc4dSJohannes Berg 78534d4bc4dSJohannes Berg err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); 78634d4bc4dSJohannes Berg if (err) 78734d4bc4dSJohannes Berg return err; 78834d4bc4dSJohannes Berg 789f142c6b9SJohannes Berg return ieee80211_do_open(&sdata->wdev, true); 79034d4bc4dSJohannes Berg } 79134d4bc4dSJohannes Berg 79234d4bc4dSJohannes Berg static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, 79334d4bc4dSJohannes Berg bool going_down) 79434d4bc4dSJohannes Berg { 7950d143fe1SJohannes Berg struct ieee80211_local *local = sdata->local; 796fa962b92SMichal Kazior struct fq *fq = &local->fq; 7975061b0c2SJohannes Berg unsigned long flags; 7985061b0c2SJohannes Berg struct sk_buff *skb, *tmp; 799e8975581SJohannes Berg u32 hw_reconf_flags = 0; 80009f4114eSJohannes Berg int i, flushed; 801397a7a24SMichael Braun struct ps_data *ps; 802d2859df5SJanusz Dziedzic struct cfg80211_chan_def chandef; 80346238845SJohannes Berg bool cancel_scan; 804167e33f4SAyala Beker struct cfg80211_nan_func *func; 8050d143fe1SJohannes Berg 806c29acf20SRajkumar Manoharan clear_bit(SDATA_STATE_RUNNING, &sdata->state); 807c29acf20SRajkumar Manoharan 80846238845SJohannes Berg cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; 80946238845SJohannes Berg if (cancel_scan) 810352ffad6SBrian Cavagnolo ieee80211_scan_cancel(local); 811352ffad6SBrian Cavagnolo 8120d143fe1SJohannes Berg /* 8130d143fe1SJohannes Berg * Stop TX on this interface first. 8140d143fe1SJohannes Berg */ 815f142c6b9SJohannes Berg if (sdata->dev) 81634d4bc4dSJohannes Berg netif_tx_stop_all_queues(sdata->dev); 8170d143fe1SJohannes Berg 818c8f994eeSJohannes Berg ieee80211_roc_purge(local, sdata); 819af6b6374SJohannes Berg 8208ffcc704SEmmanuel Grumbach switch (sdata->vif.type) { 8218ffcc704SEmmanuel Grumbach case NL80211_IFTYPE_STATION: 822572078beSJohannes Berg ieee80211_mgd_stop(sdata); 8238ffcc704SEmmanuel Grumbach break; 8248ffcc704SEmmanuel Grumbach case NL80211_IFTYPE_ADHOC: 825cd7760e6SSimon Wunderlich ieee80211_ibss_stop(sdata); 8268ffcc704SEmmanuel Grumbach break; 8278ffcc704SEmmanuel Grumbach case NL80211_IFTYPE_AP: 8288ffcc704SEmmanuel Grumbach cancel_work_sync(&sdata->u.ap.request_smps_work); 8298ffcc704SEmmanuel Grumbach break; 830f64331d5SJohannes Berg case NL80211_IFTYPE_MONITOR: 831f64331d5SJohannes Berg if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) 832f64331d5SJohannes Berg break; 833f64331d5SJohannes Berg list_del_rcu(&sdata->u.mntr.list); 834f64331d5SJohannes Berg break; 8358ffcc704SEmmanuel Grumbach default: 8368ffcc704SEmmanuel Grumbach break; 8378ffcc704SEmmanuel Grumbach } 838cd7760e6SSimon Wunderlich 839af6b6374SJohannes Berg /* 8400d143fe1SJohannes Berg * Remove all stations associated with this interface. 8410d143fe1SJohannes Berg * 8420d143fe1SJohannes Berg * This must be done before calling ops->remove_interface() 8430d143fe1SJohannes Berg * because otherwise we can later invoke ops->sta_notify() 8440d143fe1SJohannes Berg * whenever the STAs are removed, and that invalidates driver 8450d143fe1SJohannes Berg * assumptions about always getting a vif pointer that is valid 8460d143fe1SJohannes Berg * (because if we remove a STA after ops->remove_interface() 8470d143fe1SJohannes Berg * the driver will have removed the vif info already!) 8480d143fe1SJohannes Berg * 8495eb8f4d7SJohannes Berg * In WDS mode a station must exist here and be flushed, for 8505eb8f4d7SJohannes Berg * AP_VLANs stations may exist since there's nothing else that 8515eb8f4d7SJohannes Berg * would have removed them, but in other modes there shouldn't 8525eb8f4d7SJohannes Berg * be any stations. 8530d143fe1SJohannes Berg */ 854d34ba216SJohannes Berg flushed = sta_info_flush(sdata); 8555eb8f4d7SJohannes Berg WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 8565eb8f4d7SJohannes Berg ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || 8575eb8f4d7SJohannes Berg (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1))); 8580d143fe1SJohannes Berg 859df140465SJohannes Berg /* don't count this interface for allmulti while it is down */ 8600d143fe1SJohannes Berg if (sdata->flags & IEEE80211_SDATA_ALLMULTI) 8610d143fe1SJohannes Berg atomic_dec(&local->iff_allmultis); 8620d143fe1SJohannes Berg 8637be5086dSJohannes Berg if (sdata->vif.type == NL80211_IFTYPE_AP) { 864e3b90ca2SIgor Perminov local->fif_pspoll--; 8657be5086dSJohannes Berg local->fif_probe_req--; 8667be5086dSJohannes Berg } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 8677be5086dSJohannes Berg local->fif_probe_req--; 8687be5086dSJohannes Berg } 869e3b90ca2SIgor Perminov 870f142c6b9SJohannes Berg if (sdata->dev) { 87134d4bc4dSJohannes Berg netif_addr_lock_bh(sdata->dev); 8723b8d81e0SJohannes Berg spin_lock_bh(&local->filter_lock); 87334d4bc4dSJohannes Berg __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, 87434d4bc4dSJohannes Berg sdata->dev->addr_len); 8753b8d81e0SJohannes Berg spin_unlock_bh(&local->filter_lock); 87634d4bc4dSJohannes Berg netif_addr_unlock_bh(sdata->dev); 877f142c6b9SJohannes Berg } 8783ac64beeSJohannes Berg 8797cbf0ba5SVivek Natarajan del_timer_sync(&local->dynamic_ps_timer); 8807cbf0ba5SVivek Natarajan cancel_work_sync(&local->dynamic_ps_enable_work); 8810d143fe1SJohannes Berg 88204ecd257SJohannes Berg cancel_work_sync(&sdata->recalc_smps); 883dbd72850SMichal Kazior sdata_lock(sdata); 88459af6928SMichal Kazior mutex_lock(&local->mtx); 88573da7d5bSSimon Wunderlich sdata->vif.csa_active = false; 8860c21e632SLuciano Coelho if (sdata->vif.type == NL80211_IFTYPE_STATION) 8870c21e632SLuciano Coelho sdata->u.mgd.csa_waiting_bcn = false; 888a46992b4SLuciano Coelho if (sdata->csa_block_tx) { 889a46992b4SLuciano Coelho ieee80211_wake_vif_queues(local, sdata, 890a46992b4SLuciano Coelho IEEE80211_QUEUE_STOP_REASON_CSA); 891a46992b4SLuciano Coelho sdata->csa_block_tx = false; 892a46992b4SLuciano Coelho } 89359af6928SMichal Kazior mutex_unlock(&local->mtx); 894dbd72850SMichal Kazior sdata_unlock(sdata); 89559af6928SMichal Kazior 89673da7d5bSSimon Wunderlich cancel_work_sync(&sdata->csa_finalize_work); 89704ecd257SJohannes Berg 898164eb02dSSimon Wunderlich cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 899164eb02dSSimon Wunderlich 900164eb02dSSimon Wunderlich if (sdata->wdev.cac_started) { 901d2859df5SJanusz Dziedzic chandef = sdata->vif.bss_conf.chandef; 902b2c0958bSJohannes Berg WARN_ON(local->suspended); 90334a3740dSJohannes Berg mutex_lock(&local->mtx); 904164eb02dSSimon Wunderlich ieee80211_vif_release_channel(sdata); 90534a3740dSJohannes Berg mutex_unlock(&local->mtx); 906d2859df5SJanusz Dziedzic cfg80211_cac_event(sdata->dev, &chandef, 907d2859df5SJanusz Dziedzic NL80211_RADAR_CAC_ABORTED, 908164eb02dSSimon Wunderlich GFP_KERNEL); 909164eb02dSSimon Wunderlich } 910164eb02dSSimon Wunderlich 9110d143fe1SJohannes Berg /* APs need special treatment */ 9120d143fe1SJohannes Berg if (sdata->vif.type == NL80211_IFTYPE_AP) { 91357c9fff3SJohannes Berg struct ieee80211_sub_if_data *vlan, *tmpsdata; 9140d143fe1SJohannes Berg 9150d143fe1SJohannes Berg /* down all dependent devices, that is VLANs */ 91657c9fff3SJohannes Berg list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, 9170d143fe1SJohannes Berg u.vlan.list) 9180d143fe1SJohannes Berg dev_close(vlan->dev); 9190d143fe1SJohannes Berg WARN_ON(!list_empty(&sdata->u.ap.vlans)); 920397a7a24SMichael Braun } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 921397a7a24SMichael Braun /* remove all packets in parent bc_buf pointing to this dev */ 922397a7a24SMichael Braun ps = &sdata->bss->ps; 923397a7a24SMichael Braun 924397a7a24SMichael Braun spin_lock_irqsave(&ps->bc_buf.lock, flags); 925397a7a24SMichael Braun skb_queue_walk_safe(&ps->bc_buf, skb, tmp) { 926397a7a24SMichael Braun if (skb->dev == sdata->dev) { 927397a7a24SMichael Braun __skb_unlink(skb, &ps->bc_buf); 928397a7a24SMichael Braun local->total_ps_buffered--; 929397a7a24SMichael Braun ieee80211_free_txskb(&local->hw, skb); 930397a7a24SMichael Braun } 931397a7a24SMichael Braun } 932397a7a24SMichael Braun spin_unlock_irqrestore(&ps->bc_buf.lock, flags); 9330d143fe1SJohannes Berg } 9340d143fe1SJohannes Berg 93534d4bc4dSJohannes Berg if (going_down) 9360d143fe1SJohannes Berg local->open_count--; 9370d143fe1SJohannes Berg 9380d143fe1SJohannes Berg switch (sdata->vif.type) { 9390d143fe1SJohannes Berg case NL80211_IFTYPE_AP_VLAN: 9404e141dadSMichal Kazior mutex_lock(&local->mtx); 9410d143fe1SJohannes Berg list_del(&sdata->u.vlan.list); 9424e141dadSMichal Kazior mutex_unlock(&local->mtx); 9430c2bef46SMonam Agarwal RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL); 94410b68487SFelix Fietkau /* see comment in the default case below */ 94510b68487SFelix Fietkau ieee80211_free_keys(sdata, true); 9460d143fe1SJohannes Berg /* no need to tell driver */ 9470d143fe1SJohannes Berg break; 9480d143fe1SJohannes Berg case NL80211_IFTYPE_MONITOR: 949d8212184SAviya Erenfeld if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) { 9500d143fe1SJohannes Berg local->cooked_mntrs--; 9510d143fe1SJohannes Berg break; 9520d143fe1SJohannes Berg } 9530d143fe1SJohannes Berg 9540d143fe1SJohannes Berg local->monitors--; 955e8975581SJohannes Berg if (local->monitors == 0) { 9560869aea0SJohannes Berg local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; 9570869aea0SJohannes Berg hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; 958e8975581SJohannes Berg } 9590d143fe1SJohannes Berg 96085416a4fSChristian Lamparter ieee80211_adjust_monitor_flags(sdata, -1); 9610d143fe1SJohannes Berg break; 962167e33f4SAyala Beker case NL80211_IFTYPE_NAN: 963167e33f4SAyala Beker /* clean all the functions */ 964167e33f4SAyala Beker spin_lock_bh(&sdata->u.nan.func_lock); 965167e33f4SAyala Beker 966167e33f4SAyala Beker idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, i) { 967167e33f4SAyala Beker idr_remove(&sdata->u.nan.function_inst_ids, i); 968167e33f4SAyala Beker cfg80211_free_nan_func(func); 969167e33f4SAyala Beker } 970167e33f4SAyala Beker idr_destroy(&sdata->u.nan.function_inst_ids); 971167e33f4SAyala Beker 972167e33f4SAyala Beker spin_unlock_bh(&sdata->u.nan.func_lock); 973167e33f4SAyala Beker break; 974f142c6b9SJohannes Berg case NL80211_IFTYPE_P2P_DEVICE: 975f142c6b9SJohannes Berg /* relies on synchronize_rcu() below */ 9760c2bef46SMonam Agarwal RCU_INIT_POINTER(local->p2p_sdata, NULL); 977f142c6b9SJohannes Berg /* fall through */ 9780d143fe1SJohannes Berg default: 9790b7dff4fSJohannes Berg cancel_work_sync(&sdata->work); 98035f20c14SJohannes Berg /* 98135f20c14SJohannes Berg * When we get here, the interface is marked down. 9827907c7d3SJohannes Berg * Free the remaining keys, if there are any 98310b68487SFelix Fietkau * (which can happen in AP mode if userspace sets 98410b68487SFelix Fietkau * keys before the interface is operating, and maybe 98510b68487SFelix Fietkau * also in WDS mode) 98675de9113SJohannes Berg * 9877907c7d3SJohannes Berg * Force the key freeing to always synchronize_net() 9887907c7d3SJohannes Berg * to wait for the RX path in case it is using this 98910b68487SFelix Fietkau * interface enqueuing frames at this very time on 99075de9113SJohannes Berg * another CPU. 99135f20c14SJohannes Berg */ 9927907c7d3SJohannes Berg ieee80211_free_keys(sdata, true); 9931861b845SJohannes Berg skb_queue_purge(&sdata->skb_queue); 9940d143fe1SJohannes Berg } 9950d143fe1SJohannes Berg 9960d143fe1SJohannes Berg sdata->bss = NULL; 9970d143fe1SJohannes Berg 9985061b0c2SJohannes Berg spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 9995061b0c2SJohannes Berg for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { 10005061b0c2SJohannes Berg skb_queue_walk_safe(&local->pending[i], skb, tmp) { 10015061b0c2SJohannes Berg struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 10025061b0c2SJohannes Berg if (info->control.vif == &sdata->vif) { 10035061b0c2SJohannes Berg __skb_unlink(skb, &local->pending[i]); 1004d4fa14cdSFelix Fietkau ieee80211_free_txskb(&local->hw, skb); 10055061b0c2SJohannes Berg } 10065061b0c2SJohannes Berg } 10075061b0c2SJohannes Berg } 10085061b0c2SJohannes Berg spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 1009075e0847SJohannes Berg 1010ba8c3d6fSFelix Fietkau if (sdata->vif.txq) { 1011ba8c3d6fSFelix Fietkau struct txq_info *txqi = to_txq_info(sdata->vif.txq); 1012ba8c3d6fSFelix Fietkau 1013fa962b92SMichal Kazior spin_lock_bh(&fq->lock); 1014fa962b92SMichal Kazior ieee80211_txq_purge(local, txqi); 1015fa962b92SMichal Kazior spin_unlock_bh(&fq->lock); 1016ba8c3d6fSFelix Fietkau } 1017ba8c3d6fSFelix Fietkau 1018b2c0958bSJohannes Berg if (local->open_count == 0) 1019b2c0958bSJohannes Berg ieee80211_clear_tx_pending(local); 1020b2c0958bSJohannes Berg 1021b2c0958bSJohannes Berg /* 1022b2c0958bSJohannes Berg * If the interface goes down while suspended, presumably because 1023b2c0958bSJohannes Berg * the device was unplugged and that happens before our resume, 1024b2c0958bSJohannes Berg * then the driver is already unconfigured and the remainder of 1025b2c0958bSJohannes Berg * this function isn't needed. 1026b2c0958bSJohannes Berg * XXX: what about WoWLAN? If the device has software state, e.g. 1027b2c0958bSJohannes Berg * memory allocated, it might expect teardown commands from 1028b2c0958bSJohannes Berg * mac80211 here? 1029b2c0958bSJohannes Berg */ 1030b2c0958bSJohannes Berg if (local->suspended) { 1031b2c0958bSJohannes Berg WARN_ON(local->wowlan); 1032b2c0958bSJohannes Berg WARN_ON(rtnl_dereference(local->monitor_sdata)); 1033b2c0958bSJohannes Berg return; 1034b2c0958bSJohannes Berg } 1035b2c0958bSJohannes Berg 1036b2c0958bSJohannes Berg switch (sdata->vif.type) { 1037b2c0958bSJohannes Berg case NL80211_IFTYPE_AP_VLAN: 1038b2c0958bSJohannes Berg break; 1039b2c0958bSJohannes Berg case NL80211_IFTYPE_MONITOR: 1040b2c0958bSJohannes Berg if (local->monitors == 0) 1041b2c0958bSJohannes Berg ieee80211_del_virtual_monitor(local); 1042b2c0958bSJohannes Berg 1043b2c0958bSJohannes Berg mutex_lock(&local->mtx); 1044b2c0958bSJohannes Berg ieee80211_recalc_idle(local); 1045b2c0958bSJohannes Berg mutex_unlock(&local->mtx); 104631eba5bcSFelix Fietkau 1047d8212184SAviya Erenfeld if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) 1048b2c0958bSJohannes Berg break; 104931eba5bcSFelix Fietkau 105031eba5bcSFelix Fietkau /* fall through */ 1051b2c0958bSJohannes Berg default: 1052b2c0958bSJohannes Berg if (going_down) 1053b2c0958bSJohannes Berg drv_remove_interface(local, sdata); 1054b2c0958bSJohannes Berg } 1055b2c0958bSJohannes Berg 10564a733ef1SJohannes Berg ieee80211_recalc_ps(local); 1057b2c0958bSJohannes Berg 105846238845SJohannes Berg if (cancel_scan) 105946238845SJohannes Berg flush_delayed_work(&local->scan_work); 106046238845SJohannes Berg 1061b2c0958bSJohannes Berg if (local->open_count == 0) { 1062b2c0958bSJohannes Berg ieee80211_stop_device(local); 1063b2c0958bSJohannes Berg 1064b2c0958bSJohannes Berg /* no reconfiguring after stop! */ 1065b2c0958bSJohannes Berg return; 1066b2c0958bSJohannes Berg } 1067b2c0958bSJohannes Berg 1068b2c0958bSJohannes Berg /* do after stop to avoid reconfiguring when we stop anyway */ 1069b2c0958bSJohannes Berg ieee80211_configure_filter(local); 1070b2c0958bSJohannes Berg ieee80211_hw_config(local, hw_reconf_flags); 1071b2c0958bSJohannes Berg 1072b2c0958bSJohannes Berg if (local->monitors == local->open_count) 1073075e0847SJohannes Berg ieee80211_add_virtual_monitor(local); 107434d4bc4dSJohannes Berg } 107534d4bc4dSJohannes Berg 107634d4bc4dSJohannes Berg static int ieee80211_stop(struct net_device *dev) 107734d4bc4dSJohannes Berg { 107834d4bc4dSJohannes Berg struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 107934d4bc4dSJohannes Berg 108034d4bc4dSJohannes Berg ieee80211_do_stop(sdata, true); 10815061b0c2SJohannes Berg 10820d143fe1SJohannes Berg return 0; 10830d143fe1SJohannes Berg } 10840d143fe1SJohannes Berg 10850d143fe1SJohannes Berg static void ieee80211_set_multicast_list(struct net_device *dev) 10860d143fe1SJohannes Berg { 10870d143fe1SJohannes Berg struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1088b4a4bf5dSJohannes Berg struct ieee80211_local *local = sdata->local; 1089df140465SJohannes Berg int allmulti, sdata_allmulti; 10900d143fe1SJohannes Berg 10910d143fe1SJohannes Berg allmulti = !!(dev->flags & IFF_ALLMULTI); 10920d143fe1SJohannes Berg sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); 10930d143fe1SJohannes Berg 10940d143fe1SJohannes Berg if (allmulti != sdata_allmulti) { 10950d143fe1SJohannes Berg if (dev->flags & IFF_ALLMULTI) 10960d143fe1SJohannes Berg atomic_inc(&local->iff_allmultis); 10970d143fe1SJohannes Berg else 10980d143fe1SJohannes Berg atomic_dec(&local->iff_allmultis); 10990d143fe1SJohannes Berg sdata->flags ^= IEEE80211_SDATA_ALLMULTI; 11000d143fe1SJohannes Berg } 11010d143fe1SJohannes Berg 11023b8d81e0SJohannes Berg spin_lock_bh(&local->filter_lock); 110322bedad3SJiri Pirko __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); 11043b8d81e0SJohannes Berg spin_unlock_bh(&local->filter_lock); 11053ac64beeSJohannes Berg ieee80211_queue_work(&local->hw, &local->reconfig_filter); 11060d143fe1SJohannes Berg } 11070d143fe1SJohannes Berg 110875636525SJohannes Berg /* 110975636525SJohannes Berg * Called when the netdev is removed or, by the code below, before 111075636525SJohannes Berg * the interface type changes. 111175636525SJohannes Berg */ 1112f142c6b9SJohannes Berg static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) 11132c8dccc7SJohannes Berg { 11142c8dccc7SJohannes Berg int i; 11152c8dccc7SJohannes Berg 111675636525SJohannes Berg /* free extra data */ 11177907c7d3SJohannes Berg ieee80211_free_keys(sdata, false); 11182c8dccc7SJohannes Berg 1119aee14cebSJouni Malinen ieee80211_debugfs_remove_netdev(sdata); 1120aee14cebSJouni Malinen 1121988c0f72SJohannes Berg for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) 11222c8dccc7SJohannes Berg __skb_queue_purge(&sdata->fragments[i].skb_list); 112375636525SJohannes Berg sdata->fragment_next = 0; 112475636525SJohannes Berg 112575636525SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) 11260371a08fSBob Copeland ieee80211_mesh_teardown_sdata(sdata); 112775636525SJohannes Berg } 112875636525SJohannes Berg 1129f142c6b9SJohannes Berg static void ieee80211_uninit(struct net_device *dev) 1130f142c6b9SJohannes Berg { 1131f142c6b9SJohannes Berg ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); 1132f142c6b9SJohannes Berg } 1133f142c6b9SJohannes Berg 1134cf0277e7SJohannes Berg static u16 ieee80211_netdev_select_queue(struct net_device *dev, 1135f663dd9aSJason Wang struct sk_buff *skb, 113699932d4fSDaniel Borkmann void *accel_priv, 113799932d4fSDaniel Borkmann select_queue_fallback_t fallback) 1138cf0277e7SJohannes Berg { 1139cf0277e7SJohannes Berg return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); 1140cf0277e7SJohannes Berg } 1141cf0277e7SJohannes Berg 1142bc1f4470Sstephen hemminger static void 11435a490510SJohannes Berg ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) 11445a490510SJohannes Berg { 11455a490510SJohannes Berg int i; 11465a490510SJohannes Berg 11475a490510SJohannes Berg for_each_possible_cpu(i) { 11485a490510SJohannes Berg const struct pcpu_sw_netstats *tstats; 11495a490510SJohannes Berg u64 rx_packets, rx_bytes, tx_packets, tx_bytes; 11505a490510SJohannes Berg unsigned int start; 11515a490510SJohannes Berg 11525a490510SJohannes Berg tstats = per_cpu_ptr(dev->tstats, i); 11535a490510SJohannes Berg 11545a490510SJohannes Berg do { 11555a490510SJohannes Berg start = u64_stats_fetch_begin_irq(&tstats->syncp); 11565a490510SJohannes Berg rx_packets = tstats->rx_packets; 11575a490510SJohannes Berg tx_packets = tstats->tx_packets; 11585a490510SJohannes Berg rx_bytes = tstats->rx_bytes; 11595a490510SJohannes Berg tx_bytes = tstats->tx_bytes; 11605a490510SJohannes Berg } while (u64_stats_fetch_retry_irq(&tstats->syncp, start)); 11615a490510SJohannes Berg 11625a490510SJohannes Berg stats->rx_packets += rx_packets; 11635a490510SJohannes Berg stats->tx_packets += tx_packets; 11645a490510SJohannes Berg stats->rx_bytes += rx_bytes; 11655a490510SJohannes Berg stats->tx_bytes += tx_bytes; 11665a490510SJohannes Berg } 11675a490510SJohannes Berg } 11685a490510SJohannes Berg 1169587e729eSJohannes Berg static const struct net_device_ops ieee80211_dataif_ops = { 1170587e729eSJohannes Berg .ndo_open = ieee80211_open, 1171587e729eSJohannes Berg .ndo_stop = ieee80211_stop, 1172f142c6b9SJohannes Berg .ndo_uninit = ieee80211_uninit, 1173587e729eSJohannes Berg .ndo_start_xmit = ieee80211_subif_start_xmit, 1174afc4b13dSJiri Pirko .ndo_set_rx_mode = ieee80211_set_multicast_list, 117547846c9bSJohannes Berg .ndo_set_mac_address = ieee80211_change_mac, 1176cf0277e7SJohannes Berg .ndo_select_queue = ieee80211_netdev_select_queue, 11775a490510SJohannes Berg .ndo_get_stats64 = ieee80211_get_stats64, 1178587e729eSJohannes Berg }; 1179587e729eSJohannes Berg 1180cf0277e7SJohannes Berg static u16 ieee80211_monitor_select_queue(struct net_device *dev, 1181f663dd9aSJason Wang struct sk_buff *skb, 118299932d4fSDaniel Borkmann void *accel_priv, 118399932d4fSDaniel Borkmann select_queue_fallback_t fallback) 1184cf0277e7SJohannes Berg { 1185cf0277e7SJohannes Berg struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1186cf0277e7SJohannes Berg struct ieee80211_local *local = sdata->local; 1187cf0277e7SJohannes Berg struct ieee80211_hdr *hdr; 1188cf0277e7SJohannes Berg struct ieee80211_radiotap_header *rtap = (void *)skb->data; 1189cf0277e7SJohannes Berg 119032c5057bSJohannes Berg if (local->hw.queues < IEEE80211_NUM_ACS) 1191cf0277e7SJohannes Berg return 0; 1192cf0277e7SJohannes Berg 1193cf0277e7SJohannes Berg if (skb->len < 4 || 1194b49bb574SJohannes Berg skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */) 1195cf0277e7SJohannes Berg return 0; /* doesn't matter, frame will be dropped */ 1196cf0277e7SJohannes Berg 1197b49bb574SJohannes Berg hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); 1198cf0277e7SJohannes Berg 119900e96decSYoni Divinsky return ieee80211_select_queue_80211(sdata, skb, hdr); 1200cf0277e7SJohannes Berg } 1201cf0277e7SJohannes Berg 1202587e729eSJohannes Berg static const struct net_device_ops ieee80211_monitorif_ops = { 1203587e729eSJohannes Berg .ndo_open = ieee80211_open, 1204587e729eSJohannes Berg .ndo_stop = ieee80211_stop, 1205f142c6b9SJohannes Berg .ndo_uninit = ieee80211_uninit, 1206587e729eSJohannes Berg .ndo_start_xmit = ieee80211_monitor_start_xmit, 1207afc4b13dSJiri Pirko .ndo_set_rx_mode = ieee80211_set_multicast_list, 120831eba5bcSFelix Fietkau .ndo_set_mac_address = ieee80211_change_mac, 1209cf0277e7SJohannes Berg .ndo_select_queue = ieee80211_monitor_select_queue, 12105a490510SJohannes Berg .ndo_get_stats64 = ieee80211_get_stats64, 1211587e729eSJohannes Berg }; 1212587e729eSJohannes Berg 12135a490510SJohannes Berg static void ieee80211_if_free(struct net_device *dev) 12145a490510SJohannes Berg { 12155a490510SJohannes Berg free_percpu(dev->tstats); 12165a490510SJohannes Berg free_netdev(dev); 12175a490510SJohannes Berg } 12185a490510SJohannes Berg 1219587e729eSJohannes Berg static void ieee80211_if_setup(struct net_device *dev) 1220587e729eSJohannes Berg { 1221587e729eSJohannes Berg ether_setup(dev); 1222550fd08cSNeil Horman dev->priv_flags &= ~IFF_TX_SKB_SHARING; 1223587e729eSJohannes Berg dev->netdev_ops = &ieee80211_dataif_ops; 12245a490510SJohannes Berg dev->destructor = ieee80211_if_free; 1225587e729eSJohannes Berg } 1226587e729eSJohannes Berg 122780a83cfcSMichal Kazior static void ieee80211_if_setup_no_queue(struct net_device *dev) 122880a83cfcSMichal Kazior { 122980a83cfcSMichal Kazior ieee80211_if_setup(dev); 123080a83cfcSMichal Kazior dev->priv_flags |= IFF_NO_QUEUE; 123180a83cfcSMichal Kazior } 123280a83cfcSMichal Kazior 12331fa57d01SJohannes Berg static void ieee80211_iface_work(struct work_struct *work) 12341fa57d01SJohannes Berg { 12351fa57d01SJohannes Berg struct ieee80211_sub_if_data *sdata = 12361fa57d01SJohannes Berg container_of(work, struct ieee80211_sub_if_data, work); 12371fa57d01SJohannes Berg struct ieee80211_local *local = sdata->local; 12381fa57d01SJohannes Berg struct sk_buff *skb; 1239344eec67SJohannes Berg struct sta_info *sta; 12401fa57d01SJohannes Berg 12411fa57d01SJohannes Berg if (!ieee80211_sdata_running(sdata)) 12421fa57d01SJohannes Berg return; 12431fa57d01SJohannes Berg 1244fc58c47eSAndrei Otcheretianski if (test_bit(SCAN_SW_SCANNING, &local->scanning)) 12451fa57d01SJohannes Berg return; 12461fa57d01SJohannes Berg 12474afaff17SEmmanuel Grumbach if (!ieee80211_can_run_worker(local)) 12481fa57d01SJohannes Berg return; 12491fa57d01SJohannes Berg 12501fa57d01SJohannes Berg /* first process frames */ 12511fa57d01SJohannes Berg while ((skb = skb_dequeue(&sdata->skb_queue))) { 1252bed7ee6eSJohannes Berg struct ieee80211_mgmt *mgmt = (void *)skb->data; 1253bed7ee6eSJohannes Berg 1254*699cb58cSJohannes Berg if (ieee80211_is_action(mgmt->frame_control) && 1255bed7ee6eSJohannes Berg mgmt->u.action.category == WLAN_CATEGORY_BACK) { 1256bed7ee6eSJohannes Berg int len = skb->len; 1257bed7ee6eSJohannes Berg 1258a93e3644SJohannes Berg mutex_lock(&local->sta_mtx); 1259875ae5f6SFelix Fietkau sta = sta_info_get_bss(sdata, mgmt->sa); 1260bed7ee6eSJohannes Berg if (sta) { 1261bed7ee6eSJohannes Berg switch (mgmt->u.action.u.addba_req.action_code) { 1262bed7ee6eSJohannes Berg case WLAN_ACTION_ADDBA_REQ: 1263bed7ee6eSJohannes Berg ieee80211_process_addba_request( 1264bed7ee6eSJohannes Berg local, sta, mgmt, len); 1265bed7ee6eSJohannes Berg break; 1266bed7ee6eSJohannes Berg case WLAN_ACTION_ADDBA_RESP: 1267bed7ee6eSJohannes Berg ieee80211_process_addba_resp(local, sta, 1268bed7ee6eSJohannes Berg mgmt, len); 1269bed7ee6eSJohannes Berg break; 1270bed7ee6eSJohannes Berg case WLAN_ACTION_DELBA: 1271bed7ee6eSJohannes Berg ieee80211_process_delba(sdata, sta, 1272bed7ee6eSJohannes Berg mgmt, len); 1273bed7ee6eSJohannes Berg break; 1274bed7ee6eSJohannes Berg default: 1275bed7ee6eSJohannes Berg WARN_ON(1); 1276bed7ee6eSJohannes Berg break; 1277bed7ee6eSJohannes Berg } 1278bed7ee6eSJohannes Berg } 1279a93e3644SJohannes Berg mutex_unlock(&local->sta_mtx); 128023a1f8d4SSara Sharon } else if (ieee80211_is_action(mgmt->frame_control) && 128123a1f8d4SSara Sharon mgmt->u.action.category == WLAN_CATEGORY_VHT) { 128223a1f8d4SSara Sharon switch (mgmt->u.action.u.vht_group_notif.action_code) { 1283d2941df8SJohannes Berg case WLAN_VHT_ACTION_OPMODE_NOTIF: { 1284d2941df8SJohannes Berg struct ieee80211_rx_status *status; 1285d2941df8SJohannes Berg enum nl80211_band band; 1286d2941df8SJohannes Berg u8 opmode; 1287d2941df8SJohannes Berg 1288d2941df8SJohannes Berg status = IEEE80211_SKB_RXCB(skb); 1289d2941df8SJohannes Berg band = status->band; 1290d2941df8SJohannes Berg opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; 1291d2941df8SJohannes Berg 1292d2941df8SJohannes Berg mutex_lock(&local->sta_mtx); 1293d2941df8SJohannes Berg sta = sta_info_get_bss(sdata, mgmt->sa); 1294d2941df8SJohannes Berg 1295d2941df8SJohannes Berg if (sta) 1296d2941df8SJohannes Berg ieee80211_vht_handle_opmode(sdata, sta, 1297d2941df8SJohannes Berg opmode, 1298d2941df8SJohannes Berg band); 1299d2941df8SJohannes Berg 1300d2941df8SJohannes Berg mutex_unlock(&local->sta_mtx); 1301d2941df8SJohannes Berg break; 1302d2941df8SJohannes Berg } 130323a1f8d4SSara Sharon case WLAN_VHT_ACTION_GROUPID_MGMT: 130423a1f8d4SSara Sharon ieee80211_process_mu_groups(sdata, mgmt); 130523a1f8d4SSara Sharon break; 130623a1f8d4SSara Sharon default: 130723a1f8d4SSara Sharon WARN_ON(1); 130823a1f8d4SSara Sharon break; 130923a1f8d4SSara Sharon } 1310344eec67SJohannes Berg } else if (ieee80211_is_data_qos(mgmt->frame_control)) { 1311344eec67SJohannes Berg struct ieee80211_hdr *hdr = (void *)mgmt; 1312344eec67SJohannes Berg /* 1313344eec67SJohannes Berg * So the frame isn't mgmt, but frame_control 1314344eec67SJohannes Berg * is at the right place anyway, of course, so 1315344eec67SJohannes Berg * the if statement is correct. 1316344eec67SJohannes Berg * 1317344eec67SJohannes Berg * Warn if we have other data frame types here, 1318344eec67SJohannes Berg * they must not get here. 1319344eec67SJohannes Berg */ 1320344eec67SJohannes Berg WARN_ON(hdr->frame_control & 1321344eec67SJohannes Berg cpu_to_le16(IEEE80211_STYPE_NULLFUNC)); 1322344eec67SJohannes Berg WARN_ON(!(hdr->seq_ctrl & 1323344eec67SJohannes Berg cpu_to_le16(IEEE80211_SCTL_FRAG))); 1324344eec67SJohannes Berg /* 1325344eec67SJohannes Berg * This was a fragment of a frame, received while 1326344eec67SJohannes Berg * a block-ack session was active. That cannot be 1327344eec67SJohannes Berg * right, so terminate the session. 1328344eec67SJohannes Berg */ 1329a93e3644SJohannes Berg mutex_lock(&local->sta_mtx); 1330875ae5f6SFelix Fietkau sta = sta_info_get_bss(sdata, mgmt->sa); 1331344eec67SJohannes Berg if (sta) { 1332344eec67SJohannes Berg u16 tid = *ieee80211_get_qos_ctl(hdr) & 1333344eec67SJohannes Berg IEEE80211_QOS_CTL_TID_MASK; 1334344eec67SJohannes Berg 1335344eec67SJohannes Berg __ieee80211_stop_rx_ba_session( 1336344eec67SJohannes Berg sta, tid, WLAN_BACK_RECIPIENT, 133753f73c09SJohannes Berg WLAN_REASON_QSTA_REQUIRE_SETUP, 133853f73c09SJohannes Berg true); 1339344eec67SJohannes Berg } 1340a93e3644SJohannes Berg mutex_unlock(&local->sta_mtx); 1341bed7ee6eSJohannes Berg } else switch (sdata->vif.type) { 13421fa57d01SJohannes Berg case NL80211_IFTYPE_STATION: 13431fa57d01SJohannes Berg ieee80211_sta_rx_queued_mgmt(sdata, skb); 13441fa57d01SJohannes Berg break; 13451fa57d01SJohannes Berg case NL80211_IFTYPE_ADHOC: 13461fa57d01SJohannes Berg ieee80211_ibss_rx_queued_mgmt(sdata, skb); 13471fa57d01SJohannes Berg break; 13481fa57d01SJohannes Berg case NL80211_IFTYPE_MESH_POINT: 13491fa57d01SJohannes Berg if (!ieee80211_vif_is_mesh(&sdata->vif)) 13501fa57d01SJohannes Berg break; 13511fa57d01SJohannes Berg ieee80211_mesh_rx_queued_mgmt(sdata, skb); 13521fa57d01SJohannes Berg break; 13531fa57d01SJohannes Berg default: 13541fa57d01SJohannes Berg WARN(1, "frame for unexpected interface type"); 13551fa57d01SJohannes Berg break; 13561fa57d01SJohannes Berg } 135736b3a628SJohannes Berg 135836b3a628SJohannes Berg kfree_skb(skb); 13591fa57d01SJohannes Berg } 13601fa57d01SJohannes Berg 13611fa57d01SJohannes Berg /* then other type-dependent work */ 13621fa57d01SJohannes Berg switch (sdata->vif.type) { 13631fa57d01SJohannes Berg case NL80211_IFTYPE_STATION: 13641fa57d01SJohannes Berg ieee80211_sta_work(sdata); 13651fa57d01SJohannes Berg break; 13661fa57d01SJohannes Berg case NL80211_IFTYPE_ADHOC: 13671fa57d01SJohannes Berg ieee80211_ibss_work(sdata); 13681fa57d01SJohannes Berg break; 13691fa57d01SJohannes Berg case NL80211_IFTYPE_MESH_POINT: 13701fa57d01SJohannes Berg if (!ieee80211_vif_is_mesh(&sdata->vif)) 13711fa57d01SJohannes Berg break; 13721fa57d01SJohannes Berg ieee80211_mesh_work(sdata); 13731fa57d01SJohannes Berg break; 1374239281f8SRostislav Lisovy case NL80211_IFTYPE_OCB: 1375239281f8SRostislav Lisovy ieee80211_ocb_work(sdata); 1376239281f8SRostislav Lisovy break; 13771fa57d01SJohannes Berg default: 13781fa57d01SJohannes Berg break; 13791fa57d01SJohannes Berg } 13801fa57d01SJohannes Berg } 13811fa57d01SJohannes Berg 138204ecd257SJohannes Berg static void ieee80211_recalc_smps_work(struct work_struct *work) 138304ecd257SJohannes Berg { 138404ecd257SJohannes Berg struct ieee80211_sub_if_data *sdata = 138504ecd257SJohannes Berg container_of(work, struct ieee80211_sub_if_data, recalc_smps); 138604ecd257SJohannes Berg 138704ecd257SJohannes Berg ieee80211_recalc_smps(sdata); 138804ecd257SJohannes Berg } 13891fa57d01SJohannes Berg 139075636525SJohannes Berg /* 139175636525SJohannes Berg * Helper function to initialise an interface to a specific type. 139275636525SJohannes Berg */ 139375636525SJohannes Berg static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, 139405c914feSJohannes Berg enum nl80211_iftype type) 139575636525SJohannes Berg { 1396239281f8SRostislav Lisovy static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff, 1397239281f8SRostislav Lisovy 0xff, 0xff, 0xff}; 1398239281f8SRostislav Lisovy 139975636525SJohannes Berg /* clear type-dependent union */ 140075636525SJohannes Berg memset(&sdata->u, 0, sizeof(sdata->u)); 140175636525SJohannes Berg 140275636525SJohannes Berg /* and set some type-dependent values */ 140375636525SJohannes Berg sdata->vif.type = type; 14042ca27bcfSJohannes Berg sdata->vif.p2p = false; 140560719ffdSJohannes Berg sdata->wdev.iftype = type; 140675636525SJohannes Berg 1407a621fa4dSJohannes Berg sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); 1408a621fa4dSJohannes Berg sdata->control_port_no_encrypt = false; 14092475b1ccSMax Stepanov sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1410d3a58df8SAvraham Stern sdata->vif.bss_conf.idle = true; 1411a621fa4dSJohannes Berg 1412b53be792SSimon Wunderlich sdata->noack_map = 0; 1413b53be792SSimon Wunderlich 1414f142c6b9SJohannes Berg /* only monitor/p2p-device differ */ 1415f142c6b9SJohannes Berg if (sdata->dev) { 1416f142c6b9SJohannes Berg sdata->dev->netdev_ops = &ieee80211_dataif_ops; 141775636525SJohannes Berg sdata->dev->type = ARPHRD_ETHER; 1418f142c6b9SJohannes Berg } 141975636525SJohannes Berg 142035f20c14SJohannes Berg skb_queue_head_init(&sdata->skb_queue); 14211fa57d01SJohannes Berg INIT_WORK(&sdata->work, ieee80211_iface_work); 142204ecd257SJohannes Berg INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); 142373da7d5bSSimon Wunderlich INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work); 1424484298adSMichal Kazior INIT_LIST_HEAD(&sdata->assigned_chanctx_list); 1425e3afb920SMichal Kazior INIT_LIST_HEAD(&sdata->reserved_chanctx_list); 142635f20c14SJohannes Berg 142775636525SJohannes Berg switch (type) { 14282ca27bcfSJohannes Berg case NL80211_IFTYPE_P2P_GO: 14292ca27bcfSJohannes Berg type = NL80211_IFTYPE_AP; 14302ca27bcfSJohannes Berg sdata->vif.type = type; 14312ca27bcfSJohannes Berg sdata->vif.p2p = true; 14322ca27bcfSJohannes Berg /* fall through */ 143305c914feSJohannes Berg case NL80211_IFTYPE_AP: 1434d012a605SMarco Porsch skb_queue_head_init(&sdata->u.ap.ps.bc_buf); 143575636525SJohannes Berg INIT_LIST_HEAD(&sdata->u.ap.vlans); 1436687da132SEmmanuel Grumbach INIT_WORK(&sdata->u.ap.request_smps_work, 1437687da132SEmmanuel Grumbach ieee80211_request_smps_ap_work); 1438ad2d223aSJohannes Berg sdata->vif.bss_conf.bssid = sdata->vif.addr; 1439687da132SEmmanuel Grumbach sdata->u.ap.req_smps = IEEE80211_SMPS_OFF; 144075636525SJohannes Berg break; 14412ca27bcfSJohannes Berg case NL80211_IFTYPE_P2P_CLIENT: 14422ca27bcfSJohannes Berg type = NL80211_IFTYPE_STATION; 14432ca27bcfSJohannes Berg sdata->vif.type = type; 14442ca27bcfSJohannes Berg sdata->vif.p2p = true; 14452ca27bcfSJohannes Berg /* fall through */ 144605c914feSJohannes Berg case NL80211_IFTYPE_STATION: 1447ad2d223aSJohannes Berg sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; 14489c6bd790SJohannes Berg ieee80211_sta_setup_sdata(sdata); 1449472dbc45SJohannes Berg break; 14506e0bd6c3SRostislav Lisovy case NL80211_IFTYPE_OCB: 1451239281f8SRostislav Lisovy sdata->vif.bss_conf.bssid = bssid_wildcard; 1452239281f8SRostislav Lisovy ieee80211_ocb_setup_sdata(sdata); 14536e0bd6c3SRostislav Lisovy break; 145446900298SJohannes Berg case NL80211_IFTYPE_ADHOC: 1455ad2d223aSJohannes Berg sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 145646900298SJohannes Berg ieee80211_ibss_setup_sdata(sdata); 145746900298SJohannes Berg break; 145805c914feSJohannes Berg case NL80211_IFTYPE_MESH_POINT: 145975636525SJohannes Berg if (ieee80211_vif_is_mesh(&sdata->vif)) 146075636525SJohannes Berg ieee80211_mesh_init_sdata(sdata); 146175636525SJohannes Berg break; 146205c914feSJohannes Berg case NL80211_IFTYPE_MONITOR: 146375636525SJohannes Berg sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP; 1464587e729eSJohannes Berg sdata->dev->netdev_ops = &ieee80211_monitorif_ops; 1465d8212184SAviya Erenfeld sdata->u.mntr.flags = MONITOR_FLAG_CONTROL | 146675636525SJohannes Berg MONITOR_FLAG_OTHER_BSS; 146775636525SJohannes Berg break; 146805c914feSJohannes Berg case NL80211_IFTYPE_WDS: 1469ad2d223aSJohannes Berg sdata->vif.bss_conf.bssid = NULL; 1470ad2d223aSJohannes Berg break; 1471167e33f4SAyala Beker case NL80211_IFTYPE_NAN: 1472167e33f4SAyala Beker idr_init(&sdata->u.nan.function_inst_ids); 1473167e33f4SAyala Beker spin_lock_init(&sdata->u.nan.func_lock); 1474167e33f4SAyala Beker sdata->vif.bss_conf.bssid = sdata->vif.addr; 1475167e33f4SAyala Beker break; 147605c914feSJohannes Berg case NL80211_IFTYPE_AP_VLAN: 147798104fdeSJohannes Berg case NL80211_IFTYPE_P2P_DEVICE: 1478ad2d223aSJohannes Berg sdata->vif.bss_conf.bssid = sdata->vif.addr; 1479f142c6b9SJohannes Berg break; 148005c914feSJohannes Berg case NL80211_IFTYPE_UNSPECIFIED: 14812e161f78SJohannes Berg case NUM_NL80211_IFTYPES: 148275636525SJohannes Berg BUG(); 148375636525SJohannes Berg break; 148475636525SJohannes Berg } 148575636525SJohannes Berg 148675636525SJohannes Berg ieee80211_debugfs_add_netdev(sdata); 148775636525SJohannes Berg } 148875636525SJohannes Berg 148934d4bc4dSJohannes Berg static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, 149034d4bc4dSJohannes Berg enum nl80211_iftype type) 149134d4bc4dSJohannes Berg { 149234d4bc4dSJohannes Berg struct ieee80211_local *local = sdata->local; 149334d4bc4dSJohannes Berg int ret, err; 14942ca27bcfSJohannes Berg enum nl80211_iftype internal_type = type; 14952ca27bcfSJohannes Berg bool p2p = false; 149634d4bc4dSJohannes Berg 149734d4bc4dSJohannes Berg ASSERT_RTNL(); 149834d4bc4dSJohannes Berg 149934d4bc4dSJohannes Berg if (!local->ops->change_interface) 150034d4bc4dSJohannes Berg return -EBUSY; 150134d4bc4dSJohannes Berg 150234d4bc4dSJohannes Berg switch (sdata->vif.type) { 150334d4bc4dSJohannes Berg case NL80211_IFTYPE_AP: 150434d4bc4dSJohannes Berg case NL80211_IFTYPE_STATION: 150534d4bc4dSJohannes Berg case NL80211_IFTYPE_ADHOC: 1506239281f8SRostislav Lisovy case NL80211_IFTYPE_OCB: 150734d4bc4dSJohannes Berg /* 150834d4bc4dSJohannes Berg * Could maybe also all others here? 150934d4bc4dSJohannes Berg * Just not sure how that interacts 151034d4bc4dSJohannes Berg * with the RX/config path e.g. for 151134d4bc4dSJohannes Berg * mesh. 151234d4bc4dSJohannes Berg */ 151334d4bc4dSJohannes Berg break; 151434d4bc4dSJohannes Berg default: 151534d4bc4dSJohannes Berg return -EBUSY; 151634d4bc4dSJohannes Berg } 151734d4bc4dSJohannes Berg 151834d4bc4dSJohannes Berg switch (type) { 151934d4bc4dSJohannes Berg case NL80211_IFTYPE_AP: 152034d4bc4dSJohannes Berg case NL80211_IFTYPE_STATION: 152134d4bc4dSJohannes Berg case NL80211_IFTYPE_ADHOC: 1522239281f8SRostislav Lisovy case NL80211_IFTYPE_OCB: 152334d4bc4dSJohannes Berg /* 152434d4bc4dSJohannes Berg * Could probably support everything 152534d4bc4dSJohannes Berg * but WDS here (WDS do_open can fail 152634d4bc4dSJohannes Berg * under memory pressure, which this 152734d4bc4dSJohannes Berg * code isn't prepared to handle). 152834d4bc4dSJohannes Berg */ 152934d4bc4dSJohannes Berg break; 15302ca27bcfSJohannes Berg case NL80211_IFTYPE_P2P_CLIENT: 15312ca27bcfSJohannes Berg p2p = true; 15322ca27bcfSJohannes Berg internal_type = NL80211_IFTYPE_STATION; 15332ca27bcfSJohannes Berg break; 15342ca27bcfSJohannes Berg case NL80211_IFTYPE_P2P_GO: 15352ca27bcfSJohannes Berg p2p = true; 15362ca27bcfSJohannes Berg internal_type = NL80211_IFTYPE_AP; 15372ca27bcfSJohannes Berg break; 153834d4bc4dSJohannes Berg default: 153934d4bc4dSJohannes Berg return -EBUSY; 154034d4bc4dSJohannes Berg } 154134d4bc4dSJohannes Berg 15422ca27bcfSJohannes Berg ret = ieee80211_check_concurrent_iface(sdata, internal_type); 154334d4bc4dSJohannes Berg if (ret) 154434d4bc4dSJohannes Berg return ret; 154534d4bc4dSJohannes Berg 154634d4bc4dSJohannes Berg ieee80211_do_stop(sdata, false); 154734d4bc4dSJohannes Berg 1548f142c6b9SJohannes Berg ieee80211_teardown_sdata(sdata); 154934d4bc4dSJohannes Berg 15502ca27bcfSJohannes Berg ret = drv_change_interface(local, sdata, internal_type, p2p); 155134d4bc4dSJohannes Berg if (ret) 1552a9865538SJohannes Berg type = ieee80211_vif_type_p2p(&sdata->vif); 155334d4bc4dSJohannes Berg 15543a25a8c8SJohannes Berg /* 15553a25a8c8SJohannes Berg * Ignore return value here, there's not much we can do since 15563a25a8c8SJohannes Berg * the driver changed the interface type internally already. 15573a25a8c8SJohannes Berg * The warnings will hopefully make driver authors fix it :-) 15583a25a8c8SJohannes Berg */ 1559a9865538SJohannes Berg ieee80211_check_queues(sdata, type); 15603a25a8c8SJohannes Berg 156134d4bc4dSJohannes Berg ieee80211_setup_sdata(sdata, type); 156234d4bc4dSJohannes Berg 1563f142c6b9SJohannes Berg err = ieee80211_do_open(&sdata->wdev, false); 156434d4bc4dSJohannes Berg WARN(err, "type change: do_open returned %d", err); 156534d4bc4dSJohannes Berg 156634d4bc4dSJohannes Berg return ret; 156734d4bc4dSJohannes Berg } 156834d4bc4dSJohannes Berg 1569f3947e2dSJohannes Berg int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 157005c914feSJohannes Berg enum nl80211_iftype type) 157175636525SJohannes Berg { 157234d4bc4dSJohannes Berg int ret; 157334d4bc4dSJohannes Berg 1574f3947e2dSJohannes Berg ASSERT_RTNL(); 1575f3947e2dSJohannes Berg 15762ca27bcfSJohannes Berg if (type == ieee80211_vif_type_p2p(&sdata->vif)) 1577f3947e2dSJohannes Berg return 0; 1578f3947e2dSJohannes Berg 157934d4bc4dSJohannes Berg if (ieee80211_sdata_running(sdata)) { 158034d4bc4dSJohannes Berg ret = ieee80211_runtime_change_iftype(sdata, type); 158134d4bc4dSJohannes Berg if (ret) 158234d4bc4dSJohannes Berg return ret; 158334d4bc4dSJohannes Berg } else { 158475636525SJohannes Berg /* Purge and reset type-dependent state. */ 1585f142c6b9SJohannes Berg ieee80211_teardown_sdata(sdata); 158675636525SJohannes Berg ieee80211_setup_sdata(sdata, type); 158734d4bc4dSJohannes Berg } 158875636525SJohannes Berg 158975636525SJohannes Berg /* reset some values that shouldn't be kept across type changes */ 15909bc383deSJohannes Berg if (type == NL80211_IFTYPE_STATION) 15919bc383deSJohannes Berg sdata->u.mgd.use_4addr = false; 1592f3947e2dSJohannes Berg 1593f3947e2dSJohannes Berg return 0; 159475636525SJohannes Berg } 159575636525SJohannes Berg 1596fa9029f8SJohannes Berg static void ieee80211_assign_perm_addr(struct ieee80211_local *local, 1597f142c6b9SJohannes Berg u8 *perm_addr, enum nl80211_iftype type) 1598fa9029f8SJohannes Berg { 1599fa9029f8SJohannes Berg struct ieee80211_sub_if_data *sdata; 1600fa9029f8SJohannes Berg u64 mask, start, addr, val, inc; 1601fa9029f8SJohannes Berg u8 *m; 1602fa9029f8SJohannes Berg u8 tmp_addr[ETH_ALEN]; 1603fa9029f8SJohannes Berg int i; 1604fa9029f8SJohannes Berg 1605fa9029f8SJohannes Berg /* default ... something at least */ 1606f142c6b9SJohannes Berg memcpy(perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN); 1607fa9029f8SJohannes Berg 1608fa9029f8SJohannes Berg if (is_zero_ether_addr(local->hw.wiphy->addr_mask) && 1609fa9029f8SJohannes Berg local->hw.wiphy->n_addresses <= 1) 1610fa9029f8SJohannes Berg return; 1611fa9029f8SJohannes Berg 1612fa9029f8SJohannes Berg mutex_lock(&local->iflist_mtx); 1613fa9029f8SJohannes Berg 1614fa9029f8SJohannes Berg switch (type) { 1615fa9029f8SJohannes Berg case NL80211_IFTYPE_MONITOR: 1616fa9029f8SJohannes Berg /* doesn't matter */ 1617fa9029f8SJohannes Berg break; 1618fa9029f8SJohannes Berg case NL80211_IFTYPE_WDS: 1619fa9029f8SJohannes Berg case NL80211_IFTYPE_AP_VLAN: 1620fa9029f8SJohannes Berg /* match up with an AP interface */ 1621fa9029f8SJohannes Berg list_for_each_entry(sdata, &local->interfaces, list) { 1622fa9029f8SJohannes Berg if (sdata->vif.type != NL80211_IFTYPE_AP) 1623fa9029f8SJohannes Berg continue; 1624f142c6b9SJohannes Berg memcpy(perm_addr, sdata->vif.addr, ETH_ALEN); 1625fa9029f8SJohannes Berg break; 1626fa9029f8SJohannes Berg } 1627fa9029f8SJohannes Berg /* keep default if no AP interface present */ 1628fa9029f8SJohannes Berg break; 16296d71117aSJohannes Berg case NL80211_IFTYPE_P2P_CLIENT: 16306d71117aSJohannes Berg case NL80211_IFTYPE_P2P_GO: 163130686bf7SJohannes Berg if (ieee80211_hw_check(&local->hw, P2P_DEV_ADDR_FOR_INTF)) { 16326d71117aSJohannes Berg list_for_each_entry(sdata, &local->interfaces, list) { 16336d71117aSJohannes Berg if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) 16346d71117aSJohannes Berg continue; 16356d71117aSJohannes Berg if (!ieee80211_sdata_running(sdata)) 16366d71117aSJohannes Berg continue; 16376d71117aSJohannes Berg memcpy(perm_addr, sdata->vif.addr, ETH_ALEN); 16386d71117aSJohannes Berg goto out_unlock; 16396d71117aSJohannes Berg } 16406d71117aSJohannes Berg } 16416d71117aSJohannes Berg /* otherwise fall through */ 1642fa9029f8SJohannes Berg default: 1643fa9029f8SJohannes Berg /* assign a new address if possible -- try n_addresses first */ 1644fa9029f8SJohannes Berg for (i = 0; i < local->hw.wiphy->n_addresses; i++) { 1645fa9029f8SJohannes Berg bool used = false; 1646fa9029f8SJohannes Berg 1647fa9029f8SJohannes Berg list_for_each_entry(sdata, &local->interfaces, list) { 1648496d7e8eSdingtianhong if (ether_addr_equal(local->hw.wiphy->addresses[i].addr, 1649496d7e8eSdingtianhong sdata->vif.addr)) { 1650fa9029f8SJohannes Berg used = true; 1651fa9029f8SJohannes Berg break; 1652fa9029f8SJohannes Berg } 1653fa9029f8SJohannes Berg } 1654fa9029f8SJohannes Berg 1655fa9029f8SJohannes Berg if (!used) { 1656f142c6b9SJohannes Berg memcpy(perm_addr, 1657fa9029f8SJohannes Berg local->hw.wiphy->addresses[i].addr, 1658fa9029f8SJohannes Berg ETH_ALEN); 1659fa9029f8SJohannes Berg break; 1660fa9029f8SJohannes Berg } 1661fa9029f8SJohannes Berg } 1662fa9029f8SJohannes Berg 1663fa9029f8SJohannes Berg /* try mask if available */ 1664fa9029f8SJohannes Berg if (is_zero_ether_addr(local->hw.wiphy->addr_mask)) 1665fa9029f8SJohannes Berg break; 1666fa9029f8SJohannes Berg 1667fa9029f8SJohannes Berg m = local->hw.wiphy->addr_mask; 1668fa9029f8SJohannes Berg mask = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | 1669fa9029f8SJohannes Berg ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | 1670fa9029f8SJohannes Berg ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); 1671fa9029f8SJohannes Berg 1672fa9029f8SJohannes Berg if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { 1673fa9029f8SJohannes Berg /* not a contiguous mask ... not handled now! */ 1674bdcbd8e0SJohannes Berg pr_info("not contiguous\n"); 1675fa9029f8SJohannes Berg break; 1676fa9029f8SJohannes Berg } 1677fa9029f8SJohannes Berg 1678ac20976dSHelmut Schaa /* 1679ac20976dSHelmut Schaa * Pick address of existing interface in case user changed 1680ac20976dSHelmut Schaa * MAC address manually, default to perm_addr. 1681ac20976dSHelmut Schaa */ 1682fa9029f8SJohannes Berg m = local->hw.wiphy->perm_addr; 1683ac20976dSHelmut Schaa list_for_each_entry(sdata, &local->interfaces, list) { 1684ac20976dSHelmut Schaa if (sdata->vif.type == NL80211_IFTYPE_MONITOR) 1685ac20976dSHelmut Schaa continue; 1686ac20976dSHelmut Schaa m = sdata->vif.addr; 1687ac20976dSHelmut Schaa break; 1688ac20976dSHelmut Schaa } 1689fa9029f8SJohannes Berg start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | 1690fa9029f8SJohannes Berg ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | 1691fa9029f8SJohannes Berg ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); 1692fa9029f8SJohannes Berg 1693fa9029f8SJohannes Berg inc = 1ULL<<__ffs64(mask); 1694fa9029f8SJohannes Berg val = (start & mask); 1695fa9029f8SJohannes Berg addr = (start & ~mask) | (val & mask); 1696fa9029f8SJohannes Berg do { 1697fa9029f8SJohannes Berg bool used = false; 1698fa9029f8SJohannes Berg 1699fa9029f8SJohannes Berg tmp_addr[5] = addr >> 0*8; 1700fa9029f8SJohannes Berg tmp_addr[4] = addr >> 1*8; 1701fa9029f8SJohannes Berg tmp_addr[3] = addr >> 2*8; 1702fa9029f8SJohannes Berg tmp_addr[2] = addr >> 3*8; 1703fa9029f8SJohannes Berg tmp_addr[1] = addr >> 4*8; 1704fa9029f8SJohannes Berg tmp_addr[0] = addr >> 5*8; 1705fa9029f8SJohannes Berg 1706fa9029f8SJohannes Berg val += inc; 1707fa9029f8SJohannes Berg 1708fa9029f8SJohannes Berg list_for_each_entry(sdata, &local->interfaces, list) { 1709496d7e8eSdingtianhong if (ether_addr_equal(tmp_addr, sdata->vif.addr)) { 1710fa9029f8SJohannes Berg used = true; 1711fa9029f8SJohannes Berg break; 1712fa9029f8SJohannes Berg } 1713fa9029f8SJohannes Berg } 1714fa9029f8SJohannes Berg 1715fa9029f8SJohannes Berg if (!used) { 1716f142c6b9SJohannes Berg memcpy(perm_addr, tmp_addr, ETH_ALEN); 1717fa9029f8SJohannes Berg break; 1718fa9029f8SJohannes Berg } 1719fa9029f8SJohannes Berg addr = (start & ~mask) | (val & mask); 1720fa9029f8SJohannes Berg } while (addr != start); 1721fa9029f8SJohannes Berg 1722fa9029f8SJohannes Berg break; 1723fa9029f8SJohannes Berg } 1724fa9029f8SJohannes Berg 17256d71117aSJohannes Berg out_unlock: 1726fa9029f8SJohannes Berg mutex_unlock(&local->iflist_mtx); 1727fa9029f8SJohannes Berg } 1728fa9029f8SJohannes Berg 17293e122be0SJohannes Berg int ieee80211_if_add(struct ieee80211_local *local, const char *name, 17306bab2e19STom Gundersen unsigned char name_assign_type, 173184efbb84SJohannes Berg struct wireless_dev **new_wdev, enum nl80211_iftype type, 17322c8dccc7SJohannes Berg struct vif_params *params) 17332c8dccc7SJohannes Berg { 1734f142c6b9SJohannes Berg struct net_device *ndev = NULL; 17352c8dccc7SJohannes Berg struct ieee80211_sub_if_data *sdata = NULL; 1736ba8c3d6fSFelix Fietkau struct txq_info *txqi; 173780a83cfcSMichal Kazior void (*if_setup)(struct net_device *dev); 173875636525SJohannes Berg int ret, i; 1739ded81f6bSJohannes Berg int txqs = 1; 17402c8dccc7SJohannes Berg 17412c8dccc7SJohannes Berg ASSERT_RTNL(); 174275636525SJohannes Berg 1743708d50edSAyala Beker if (type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN) { 1744f142c6b9SJohannes Berg struct wireless_dev *wdev; 1745f142c6b9SJohannes Berg 1746f142c6b9SJohannes Berg sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, 1747f142c6b9SJohannes Berg GFP_KERNEL); 1748f142c6b9SJohannes Berg if (!sdata) 1749f142c6b9SJohannes Berg return -ENOMEM; 1750f142c6b9SJohannes Berg wdev = &sdata->wdev; 1751f142c6b9SJohannes Berg 1752f142c6b9SJohannes Berg sdata->dev = NULL; 1753f142c6b9SJohannes Berg strlcpy(sdata->name, name, IFNAMSIZ); 1754f142c6b9SJohannes Berg ieee80211_assign_perm_addr(local, wdev->address, type); 1755f142c6b9SJohannes Berg memcpy(sdata->vif.addr, wdev->address, ETH_ALEN); 1756f142c6b9SJohannes Berg } else { 1757ba8c3d6fSFelix Fietkau int size = ALIGN(sizeof(*sdata) + local->hw.vif_data_size, 1758ba8c3d6fSFelix Fietkau sizeof(void *)); 1759ba8c3d6fSFelix Fietkau int txq_size = 0; 1760ba8c3d6fSFelix Fietkau 1761ba8c3d6fSFelix Fietkau if (local->ops->wake_tx_queue) 1762ba8c3d6fSFelix Fietkau txq_size += sizeof(struct txq_info) + 1763ba8c3d6fSFelix Fietkau local->hw.txq_data_size; 1764ba8c3d6fSFelix Fietkau 176580a83cfcSMichal Kazior if (local->ops->wake_tx_queue) 176680a83cfcSMichal Kazior if_setup = ieee80211_if_setup_no_queue; 176780a83cfcSMichal Kazior else 176880a83cfcSMichal Kazior if_setup = ieee80211_if_setup; 176980a83cfcSMichal Kazior 1770ded81f6bSJohannes Berg if (local->hw.queues >= IEEE80211_NUM_ACS) 1771ded81f6bSJohannes Berg txqs = IEEE80211_NUM_ACS; 1772ded81f6bSJohannes Berg 1773ba8c3d6fSFelix Fietkau ndev = alloc_netdev_mqs(size + txq_size, 17746bab2e19STom Gundersen name, name_assign_type, 177580a83cfcSMichal Kazior if_setup, txqs, 1); 17762c8dccc7SJohannes Berg if (!ndev) 17772c8dccc7SJohannes Berg return -ENOMEM; 1778a272a720SJohannes Berg dev_net_set(ndev, wiphy_net(local->hw.wiphy)); 17792c8dccc7SJohannes Berg 17805a490510SJohannes Berg ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 17815a490510SJohannes Berg if (!ndev->tstats) { 17825a490510SJohannes Berg free_netdev(ndev); 17835a490510SJohannes Berg return -ENOMEM; 17845a490510SJohannes Berg } 17855a490510SJohannes Berg 1786f3994eceSJohannes Berg ndev->needed_headroom = local->tx_headroom + 1787f3994eceSJohannes Berg 4*6 /* four MAC addresses */ 1788f3994eceSJohannes Berg + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ 1789f3994eceSJohannes Berg + 6 /* mesh */ 1790f3994eceSJohannes Berg + 8 /* rfc1042/bridge tunnel */ 1791f3994eceSJohannes Berg - ETH_HLEN /* ethernet hard_header_len */ 1792f3994eceSJohannes Berg + IEEE80211_ENCRYPT_HEADROOM; 1793f3994eceSJohannes Berg ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; 1794f3994eceSJohannes Berg 179559e7e707SThadeu Lima de Souza Cascardo ret = dev_alloc_name(ndev, ndev->name); 1796f142c6b9SJohannes Berg if (ret < 0) { 1797e6436be2SJohannes Berg ieee80211_if_free(ndev); 1798f142c6b9SJohannes Berg return ret; 1799f142c6b9SJohannes Berg } 180059e7e707SThadeu Lima de Souza Cascardo 1801f142c6b9SJohannes Berg ieee80211_assign_perm_addr(local, ndev->perm_addr, type); 1802b5dfae02SBen Greear if (params && is_valid_ether_addr(params->macaddr)) 1803b5dfae02SBen Greear memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN); 1804b5dfae02SBen Greear else 1805fa9029f8SJohannes Berg memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); 18062c8dccc7SJohannes Berg SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 18072c8dccc7SJohannes Berg 1808f142c6b9SJohannes Berg /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ 18093e122be0SJohannes Berg sdata = netdev_priv(ndev); 18102c8dccc7SJohannes Berg ndev->ieee80211_ptr = &sdata->wdev; 181147846c9bSJohannes Berg memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); 181247846c9bSJohannes Berg memcpy(sdata->name, ndev->name, IFNAMSIZ); 181375636525SJohannes Berg 1814ba8c3d6fSFelix Fietkau if (txq_size) { 1815ba8c3d6fSFelix Fietkau txqi = netdev_priv(ndev) + size; 1816fa962b92SMichal Kazior ieee80211_txq_init(sdata, NULL, txqi, 0); 1817ba8c3d6fSFelix Fietkau } 1818ba8c3d6fSFelix Fietkau 1819f142c6b9SJohannes Berg sdata->dev = ndev; 1820f142c6b9SJohannes Berg } 1821f142c6b9SJohannes Berg 182275636525SJohannes Berg /* initialise type-independent data */ 18232c8dccc7SJohannes Berg sdata->wdev.wiphy = local->hw.wiphy; 18242c8dccc7SJohannes Berg sdata->local = local; 182575636525SJohannes Berg 182675636525SJohannes Berg for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) 182775636525SJohannes Berg skb_queue_head_init(&sdata->fragments[i].skb_list); 182875636525SJohannes Berg 182975636525SJohannes Berg INIT_LIST_HEAD(&sdata->key_list); 183075636525SJohannes Berg 1831164eb02dSSimon Wunderlich INIT_DELAYED_WORK(&sdata->dfs_cac_timer_work, 1832164eb02dSSimon Wunderlich ieee80211_dfs_cac_timer_work); 18338d1f7ecdSJohannes Berg INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk, 18348d1f7ecdSJohannes Berg ieee80211_delayed_tailroom_dec); 183597f97b1fSJohannes Berg 183657fbcce3SJohannes Berg for (i = 0; i < NUM_NL80211_BANDS; i++) { 183737eb0b16SJouni Malinen struct ieee80211_supported_band *sband; 183837eb0b16SJouni Malinen sband = local->hw.wiphy->bands[i]; 183937eb0b16SJouni Malinen sdata->rc_rateidx_mask[i] = 184037eb0b16SJouni Malinen sband ? (1 << sband->n_bitrates) - 1 : 0; 1841b119ad6eSLorenzo Bianconi if (sband) { 1842b119ad6eSLorenzo Bianconi __le16 cap; 1843b119ad6eSLorenzo Bianconi u16 *vht_rate_mask; 1844b119ad6eSLorenzo Bianconi 184519468413SSimon Wunderlich memcpy(sdata->rc_rateidx_mcs_mask[i], 184619468413SSimon Wunderlich sband->ht_cap.mcs.rx_mask, 184719468413SSimon Wunderlich sizeof(sdata->rc_rateidx_mcs_mask[i])); 1848b119ad6eSLorenzo Bianconi 1849b119ad6eSLorenzo Bianconi cap = sband->vht_cap.vht_mcs.rx_mcs_map; 1850b119ad6eSLorenzo Bianconi vht_rate_mask = sdata->rc_rateidx_vht_mcs_mask[i]; 1851b119ad6eSLorenzo Bianconi ieee80211_get_vht_mask_from_cap(cap, vht_rate_mask); 1852b119ad6eSLorenzo Bianconi } else { 185319468413SSimon Wunderlich memset(sdata->rc_rateidx_mcs_mask[i], 0, 185419468413SSimon Wunderlich sizeof(sdata->rc_rateidx_mcs_mask[i])); 1855b119ad6eSLorenzo Bianconi memset(sdata->rc_rateidx_vht_mcs_mask[i], 0, 1856b119ad6eSLorenzo Bianconi sizeof(sdata->rc_rateidx_vht_mcs_mask[i])); 1857b119ad6eSLorenzo Bianconi } 185837eb0b16SJouni Malinen } 185975636525SJohannes Berg 18603a25a8c8SJohannes Berg ieee80211_set_default_queues(sdata); 18613a25a8c8SJohannes Berg 18621ea6f9c0SJohannes Berg sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; 18631ea6f9c0SJohannes Berg sdata->user_power_level = local->user_power_level; 18641ea6f9c0SJohannes Berg 18652475b1ccSMax Stepanov sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 18662475b1ccSMax Stepanov 186775636525SJohannes Berg /* setup type-dependent data */ 186875636525SJohannes Berg ieee80211_setup_sdata(sdata, type); 18692c8dccc7SJohannes Berg 1870f142c6b9SJohannes Berg if (ndev) { 18719bc383deSJohannes Berg if (params) { 18729bc383deSJohannes Berg ndev->ieee80211_ptr->use_4addr = params->use_4addr; 18739bc383deSJohannes Berg if (type == NL80211_IFTYPE_STATION) 18749bc383deSJohannes Berg sdata->u.mgd.use_4addr = params->use_4addr; 18759bc383deSJohannes Berg } 18769bc383deSJohannes Berg 187772d78728SArik Nemtsov ndev->features |= local->hw.netdev_features; 187872d78728SArik Nemtsov 1879b7ffbd7eSJohannes Berg netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); 1880b7ffbd7eSJohannes Berg 18819c22b4a3SJarod Wilson /* MTU range: 256 - 2304 */ 18829c22b4a3SJarod Wilson ndev->min_mtu = 256; 18839c22b4a3SJarod Wilson ndev->max_mtu = IEEE80211_MAX_DATA_LEN; 18849c22b4a3SJarod Wilson 18852c8dccc7SJohannes Berg ret = register_netdevice(ndev); 1886f142c6b9SJohannes Berg if (ret) { 1887e6436be2SJohannes Berg ieee80211_if_free(ndev); 1888f142c6b9SJohannes Berg return ret; 1889f142c6b9SJohannes Berg } 1890f142c6b9SJohannes Berg } 18912c8dccc7SJohannes Berg 1892c771c9d8SJohannes Berg mutex_lock(&local->iflist_mtx); 18932c8dccc7SJohannes Berg list_add_tail_rcu(&sdata->list, &local->interfaces); 1894c771c9d8SJohannes Berg mutex_unlock(&local->iflist_mtx); 18952c8dccc7SJohannes Berg 189684efbb84SJohannes Berg if (new_wdev) 189784efbb84SJohannes Berg *new_wdev = &sdata->wdev; 18982c8dccc7SJohannes Berg 18992c8dccc7SJohannes Berg return 0; 19002c8dccc7SJohannes Berg } 19012c8dccc7SJohannes Berg 1902f698d856SJasper Bryant-Greene void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) 19032c8dccc7SJohannes Berg { 19042c8dccc7SJohannes Berg ASSERT_RTNL(); 19052c8dccc7SJohannes Berg 1906c771c9d8SJohannes Berg mutex_lock(&sdata->local->iflist_mtx); 19072c8dccc7SJohannes Berg list_del_rcu(&sdata->list); 1908c771c9d8SJohannes Berg mutex_unlock(&sdata->local->iflist_mtx); 1909c771c9d8SJohannes Berg 19102c8dccc7SJohannes Berg synchronize_rcu(); 1911f142c6b9SJohannes Berg 1912f142c6b9SJohannes Berg if (sdata->dev) { 1913f698d856SJasper Bryant-Greene unregister_netdevice(sdata->dev); 1914f142c6b9SJohannes Berg } else { 1915f142c6b9SJohannes Berg cfg80211_unregister_wdev(&sdata->wdev); 1916835112b2SEliad Peller ieee80211_teardown_sdata(sdata); 1917f142c6b9SJohannes Berg kfree(sdata); 1918f142c6b9SJohannes Berg } 1919f142c6b9SJohannes Berg } 1920f142c6b9SJohannes Berg 1921f142c6b9SJohannes Berg void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata) 1922f142c6b9SJohannes Berg { 1923f142c6b9SJohannes Berg if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state))) 1924f142c6b9SJohannes Berg return; 1925f142c6b9SJohannes Berg ieee80211_do_stop(sdata, true); 19262c8dccc7SJohannes Berg } 19272c8dccc7SJohannes Berg 192875636525SJohannes Berg void ieee80211_remove_interfaces(struct ieee80211_local *local) 19292c8dccc7SJohannes Berg { 193075636525SJohannes Berg struct ieee80211_sub_if_data *sdata, *tmp; 1931efe117abSEric Dumazet LIST_HEAD(unreg_list); 1932f142c6b9SJohannes Berg LIST_HEAD(wdev_list); 19332c8dccc7SJohannes Berg 193475636525SJohannes Berg ASSERT_RTNL(); 193575636525SJohannes Berg 1936d8d9008cSJohannes Berg /* Before destroying the interfaces, make sure they're all stopped so 1937d8d9008cSJohannes Berg * that the hardware is stopped. Otherwise, the driver might still be 1938d8d9008cSJohannes Berg * iterating the interfaces during the shutdown, e.g. from a worker 1939d8d9008cSJohannes Berg * or from RX processing or similar, and if it does so (using atomic 1940d8d9008cSJohannes Berg * iteration) while we're manipulating the list, the iteration will 1941d8d9008cSJohannes Berg * crash. 1942d8d9008cSJohannes Berg * 1943d8d9008cSJohannes Berg * After this, the hardware should be stopped and the driver should 1944d8d9008cSJohannes Berg * have stopped all of its activities, so that we can do RCU-unaware 1945d8d9008cSJohannes Berg * manipulations of the interface list below. 1946c8aa22dbSJohannes Berg */ 1947d8d9008cSJohannes Berg cfg80211_shutdown_all_interfaces(local->hw.wiphy); 1948d8d9008cSJohannes Berg 1949d8d9008cSJohannes Berg WARN(local->open_count, "%s: open count remains %d\n", 1950d8d9008cSJohannes Berg wiphy_name(local->hw.wiphy), local->open_count); 1951c8aa22dbSJohannes Berg 1952c771c9d8SJohannes Berg mutex_lock(&local->iflist_mtx); 1953efe117abSEric Dumazet list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { 195475636525SJohannes Berg list_del(&sdata->list); 1955c771c9d8SJohannes Berg 1956f142c6b9SJohannes Berg if (sdata->dev) 1957efe117abSEric Dumazet unregister_netdevice_queue(sdata->dev, &unreg_list); 1958f142c6b9SJohannes Berg else 1959f142c6b9SJohannes Berg list_add(&sdata->list, &wdev_list); 196075636525SJohannes Berg } 1961efe117abSEric Dumazet mutex_unlock(&local->iflist_mtx); 1962efe117abSEric Dumazet unregister_netdevice_many(&unreg_list); 1963f142c6b9SJohannes Berg 1964f142c6b9SJohannes Berg list_for_each_entry_safe(sdata, tmp, &wdev_list, list) { 1965f142c6b9SJohannes Berg list_del(&sdata->list); 1966f142c6b9SJohannes Berg cfg80211_unregister_wdev(&sdata->wdev); 1967f142c6b9SJohannes Berg kfree(sdata); 1968f142c6b9SJohannes Berg } 19692c8dccc7SJohannes Berg } 19705cff20e6SJohannes Berg 197147846c9bSJohannes Berg static int netdev_notify(struct notifier_block *nb, 1972351638e7SJiri Pirko unsigned long state, void *ptr) 197347846c9bSJohannes Berg { 1974351638e7SJiri Pirko struct net_device *dev = netdev_notifier_info_to_dev(ptr); 197547846c9bSJohannes Berg struct ieee80211_sub_if_data *sdata; 197647846c9bSJohannes Berg 197747846c9bSJohannes Berg if (state != NETDEV_CHANGENAME) 19788bd811aaSZhao, Gang return NOTIFY_DONE; 197947846c9bSJohannes Berg 198047846c9bSJohannes Berg if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) 19818bd811aaSZhao, Gang return NOTIFY_DONE; 198247846c9bSJohannes Berg 198347846c9bSJohannes Berg if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) 19848bd811aaSZhao, Gang return NOTIFY_DONE; 198547846c9bSJohannes Berg 198647846c9bSJohannes Berg sdata = IEEE80211_DEV_TO_SUB_IF(dev); 19872f5265e6SJohannes Berg memcpy(sdata->name, dev->name, IFNAMSIZ); 198847846c9bSJohannes Berg ieee80211_debugfs_rename_netdev(sdata); 19898bd811aaSZhao, Gang 19908bd811aaSZhao, Gang return NOTIFY_OK; 199147846c9bSJohannes Berg } 199247846c9bSJohannes Berg 199347846c9bSJohannes Berg static struct notifier_block mac80211_netdev_notifier = { 199447846c9bSJohannes Berg .notifier_call = netdev_notify, 199547846c9bSJohannes Berg }; 199647846c9bSJohannes Berg 199747846c9bSJohannes Berg int ieee80211_iface_init(void) 199847846c9bSJohannes Berg { 199947846c9bSJohannes Berg return register_netdevice_notifier(&mac80211_netdev_notifier); 200047846c9bSJohannes Berg } 200147846c9bSJohannes Berg 200247846c9bSJohannes Berg void ieee80211_iface_exit(void) 200347846c9bSJohannes Berg { 200447846c9bSJohannes Berg unregister_netdevice_notifier(&mac80211_netdev_notifier); 200547846c9bSJohannes Berg } 200672f15d53SMichael Braun 200772f15d53SMichael Braun void ieee80211_vif_inc_num_mcast(struct ieee80211_sub_if_data *sdata) 200872f15d53SMichael Braun { 200972f15d53SMichael Braun if (sdata->vif.type == NL80211_IFTYPE_AP) 201072f15d53SMichael Braun atomic_inc(&sdata->u.ap.num_mcast_sta); 201172f15d53SMichael Braun else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 201272f15d53SMichael Braun atomic_inc(&sdata->u.vlan.num_mcast_sta); 201372f15d53SMichael Braun } 201472f15d53SMichael Braun 201572f15d53SMichael Braun void ieee80211_vif_dec_num_mcast(struct ieee80211_sub_if_data *sdata) 201672f15d53SMichael Braun { 201772f15d53SMichael Braun if (sdata->vif.type == NL80211_IFTYPE_AP) 201872f15d53SMichael Braun atomic_dec(&sdata->u.ap.num_mcast_sta); 201972f15d53SMichael Braun else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 202072f15d53SMichael Braun atomic_dec(&sdata->u.vlan.num_mcast_sta); 202172f15d53SMichael Braun } 2022