* No need to check netif_running since we do not allow
* it to start up with this invalid address.
*/
- if (compare_ether_addr(null_addr, ndev->dev_addr) == 0)
+ if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) {
memcpy(ndev->dev_addr,
local->hw.wiphy->perm_addr,
ETH_ALEN);
+ memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN);
+ }
}
/*
/* must be before the call to ieee80211_configure_filter */
local->monitors++;
if (local->monitors == 1) {
- local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
- hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
+ local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
+ hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
}
if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
local->fif_fcsfail++;
if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
local->fif_plcpfail++;
- if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+ if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
local->fif_control++;
+ local->fif_pspoll++;
+ }
if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
local->fif_other_bss++;
- spin_lock_bh(&local->filter_lock);
ieee80211_configure_filter(local);
- spin_unlock_bh(&local->filter_lock);
break;
default:
conf.vif = &sdata->vif;
if (ieee80211_vif_is_mesh(&sdata->vif)) {
local->fif_other_bss++;
- spin_lock_bh(&local->filter_lock);
ieee80211_configure_filter(local);
- spin_unlock_bh(&local->filter_lock);
ieee80211_start_mesh(sdata);
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
+ local->fif_pspoll++;
+
+ ieee80211_configure_filter(local);
}
+
changed |= ieee80211_reset_erp_info(sdata);
ieee80211_bss_info_change_notify(sdata, changed);
ieee80211_enable_keys(sdata);
}
}
- if (local->open_count == 0) {
- tasklet_enable(&local->tx_pending_tasklet);
- tasklet_enable(&local->tasklet);
- }
-
/*
* set_multicast_list will be invoked by the networking core
* which will check whether any increments here were done in
if (sdata->vif.type == NL80211_IFTYPE_STATION)
ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
- netif_tx_start_all_queues(dev);
+ netif_start_queue(dev);
return 0;
err_del_interface:
/*
* Stop TX on this interface first.
*/
- netif_tx_stop_all_queues(dev);
+ netif_stop_queue(dev);
/*
* Now delete all active aggregation sessions.
if (sdata->flags & IEEE80211_SDATA_PROMISC)
atomic_dec(&local->iff_promiscs);
+ if (sdata->vif.type == NL80211_IFTYPE_AP)
+ local->fif_pspoll--;
+
netif_addr_lock_bh(dev);
spin_lock_bh(&local->filter_lock);
__dev_addr_unsync(&local->mc_list, &local->mc_count,
&dev->mc_list, &dev->mc_count);
- ieee80211_configure_filter(local);
spin_unlock_bh(&local->filter_lock);
netif_addr_unlock_bh(dev);
+ ieee80211_configure_filter(local);
+
del_timer_sync(&local->dynamic_ps_timer);
cancel_work_sync(&local->dynamic_ps_enable_work);
local->monitors--;
if (local->monitors == 0) {
- local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
- hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
+ local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
+ hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
}
if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
local->fif_fcsfail--;
if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
local->fif_plcpfail--;
- if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+ if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
+ local->fif_pspoll--;
local->fif_control--;
+ }
if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
local->fif_other_bss--;
- spin_lock_bh(&local->filter_lock);
ieee80211_configure_filter(local);
- spin_unlock_bh(&local->filter_lock);
break;
case NL80211_IFTYPE_STATION:
del_timer_sync(&sdata->u.mgd.chswitch_timer);
local->fif_other_bss--;
atomic_dec(&local->iff_allmultis);
- spin_lock_bh(&local->filter_lock);
ieee80211_configure_filter(local);
- spin_unlock_bh(&local->filter_lock);
ieee80211_stop_mesh(sdata);
}
/* fall through */
default:
- if (local->scan_sdata == sdata) {
- if (!local->ops->hw_scan)
- cancel_delayed_work_sync(&local->scan_work);
- /*
- * The software scan can no longer run now, so we can
- * clear out the scan_sdata reference. However, the
- * hardware scan may still be running. The complete
- * function must be prepared to handle a NULL value.
- */
- local->scan_sdata = NULL;
- /*
- * The memory barrier guarantees that another CPU
- * that is hardware-scanning will now see the fact
- * that this interface is gone.
- */
- smp_mb();
- /*
- * If software scanning, complete the scan but since
- * the scan_sdata is NULL already don't send out a
- * scan event to userspace -- the scan is incomplete.
- */
- if (test_bit(SCAN_SW_SCANNING, &local->scanning))
- ieee80211_scan_completed(&local->hw, true);
- }
+ if (local->scan_sdata == sdata)
+ ieee80211_scan_cancel(local);
/*
* Disable beaconing for AP and mesh, IBSS can't
ieee80211_recalc_ps(local, -1);
if (local->open_count == 0) {
- drv_stop(local);
-
- ieee80211_led_radio(local, false);
-
- flush_workqueue(local->workqueue);
-
- tasklet_disable(&local->tx_pending_tasklet);
- tasklet_disable(&local->tasklet);
+ ieee80211_clear_tx_pending(local);
+ ieee80211_stop_device(local);
/* no reconfiguring after stop! */
hw_reconf_flags = 0;
spin_lock_bh(&local->filter_lock);
__dev_addr_sync(&local->mc_list, &local->mc_count,
&dev->mc_list, &dev->mc_count);
- ieee80211_configure_filter(local);
spin_unlock_bh(&local->filter_lock);
+ ieee80211_queue_work(&local->hw, &local->reconfig_filter);
}
/*
ieee80211_mandatory_rates(sdata->local,
sdata->local->hw.conf.channel->band);
sdata->drop_unencrypted = 0;
+ if (type == NL80211_IFTYPE_STATION)
+ sdata->u.mgd.use_4addr = false;
return 0;
}
goto fail;
memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
+ memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN);
SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
/* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
/* setup type-dependent data */
ieee80211_setup_sdata(sdata, type);
+ if (params) {
+ ndev->ieee80211_ptr->use_4addr = params->use_4addr;
+ if (type == NL80211_IFTYPE_STATION)
+ sdata->u.mgd.use_4addr = params->use_4addr;
+ }
+
ret = register_netdevice(ndev);
if (ret)
goto fail;
void ieee80211_remove_interfaces(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata, *tmp;
+ LIST_HEAD(unreg_list);
ASSERT_RTNL();
+ mutex_lock(&local->iflist_mtx);
list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
- /*
- * we cannot hold the iflist_mtx across unregister_netdevice,
- * but we only need to hold it for list modifications to lock
- * out readers since we're under the RTNL here as all other
- * writers.
- */
- mutex_lock(&local->iflist_mtx);
list_del(&sdata->list);
- mutex_unlock(&local->iflist_mtx);
- unregister_netdevice(sdata->dev);
+ unregister_netdevice_queue(sdata->dev, &unreg_list);
}
+ mutex_unlock(&local->iflist_mtx);
+ unregister_netdevice_many(&unreg_list);
}
static u32 ieee80211_idle_off(struct ieee80211_local *local,