Commit 47846c9b authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: reduce reliance on netdev

For bluetooth 3, we will most likely not have
a netdev for a virtual interface (sdata), so
prepare for that by reducing the reliance on
having a netdev. This patch moves the name
and address fields into the sdata struct and
uses them from there all over. Some work is
needed to keep them sync'ed, but that's not
a lot of work and in slow paths anyway.

In doing so, this also reduces the number of
pointer dereferences in many places, because
of things like sdata->dev->dev_addr becoming
sdata->vif.addr.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent abe60632
......@@ -659,12 +659,14 @@ struct ieee80211_conf {
* @type: type of this virtual interface
* @bss_conf: BSS configuration for this interface, either our own
* or the BSS we're associated to
* @addr: address of this interface
* @drv_priv: data area for driver use, will always be aligned to
* sizeof(void *).
*/
struct ieee80211_vif {
enum nl80211_iftype type;
struct ieee80211_bss_conf bss_conf;
u8 addr[ETH_ALEN];
/* must be last */
u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
};
......
......@@ -135,7 +135,7 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer "
"for addba resp frame\n", sdata->dev->name);
"for addba resp frame\n", sdata->name);
return;
}
......@@ -143,10 +143,10 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
memset(mgmt, 0, 24);
memcpy(mgmt->da, da, ETH_ALEN);
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
if (sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
......
......@@ -58,17 +58,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
if (!skb) {
printk(KERN_ERR "%s: failed to allocate buffer "
"for addba request frame\n", sdata->dev->name);
"for addba request frame\n", sdata->name);
return;
}
skb_reserve(skb, local->hw.extra_tx_headroom);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
memset(mgmt, 0, 24);
memcpy(mgmt->da, da, ETH_ALEN);
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
if (sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
......@@ -104,7 +104,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
if (!skb) {
printk(KERN_ERR "%s: failed to allocate buffer for "
"bar frame\n", sdata->dev->name);
"bar frame\n", sdata->name);
return;
}
skb_reserve(skb, local->hw.extra_tx_headroom);
......@@ -113,7 +113,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
IEEE80211_STYPE_BACK_REQ);
memcpy(bar->ra, ra, ETH_ALEN);
memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
bar_control |= (u16)(tid << 12);
......@@ -489,7 +489,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
printk(KERN_WARNING "%s: Not enough memory, "
"dropping start BA session", skb->dev->name);
"dropping start BA session", sdata->name);
#endif
return;
}
......@@ -621,7 +621,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
#ifdef CONFIG_MAC80211_HT_DEBUG
if (net_ratelimit())
printk(KERN_WARNING "%s: Not enough memory, "
"dropping stop BA session", skb->dev->name);
"dropping stop BA session", sdata->name);
#endif
return;
}
......
......@@ -729,7 +729,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
} else
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (compare_ether_addr(mac, dev->dev_addr) == 0)
if (compare_ether_addr(mac, sdata->vif.addr) == 0)
return -EINVAL;
if (is_multicast_ether_addr(mac))
......
......@@ -56,7 +56,7 @@ KEY_CONF_FILE(keyidx, D);
KEY_CONF_FILE(hw_key_idx, D);
KEY_FILE(flags, X);
KEY_FILE(tx_rx_count, D);
KEY_READ(ifindex, sdata->dev->ifindex, 20, "%d\n");
KEY_READ(ifindex, sdata->name, IFNAMSIZ + 2, "%s\n");
KEY_OPS(ifindex);
static ssize_t key_algorithm_read(struct file *file,
......
......@@ -280,16 +280,11 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
}
}
static int notif_registered;
void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
{
char buf[10+IFNAMSIZ];
if (!notif_registered)
return;
sprintf(buf, "netdev:%s", sdata->dev->name);
sprintf(buf, "netdev:%s", sdata->name);
sdata->debugfs.dir = debugfs_create_dir(buf,
sdata->local->hw.wiphy->debugfsdir);
add_files(sdata);
......@@ -304,58 +299,18 @@ void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
sdata->debugfs.dir = NULL;
}
static int netdev_notify(struct notifier_block *nb,
unsigned long state,
void *ndev)
void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
{
struct net_device *dev = ndev;
struct dentry *dir;
struct ieee80211_sub_if_data *sdata;
char buf[10+IFNAMSIZ];
if (state != NETDEV_CHANGENAME)
return 0;
if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
return 0;
if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
return 0;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
char buf[10 + IFNAMSIZ];
dir = sdata->debugfs.dir;
if (!dir)
return 0;
return;
sprintf(buf, "netdev:%s", dev->name);
sprintf(buf, "netdev:%s", sdata->name);
if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
"dir to %s\n", buf);
return 0;
}
static struct notifier_block mac80211_debugfs_netdev_notifier = {
.notifier_call = netdev_notify,
};
void ieee80211_debugfs_netdev_init(void)
{
int err;
err = register_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
if (err) {
printk(KERN_ERR
"mac80211: failed to install netdev notifier,"
" disabling per-netdev debugfs!\n");
} else
notif_registered = 1;
}
void ieee80211_debugfs_netdev_exit(void)
{
unregister_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
notif_registered = 0;
}
......@@ -6,8 +6,7 @@
#ifdef CONFIG_MAC80211_DEBUGFS
void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_netdev_init(void);
void ieee80211_debugfs_netdev_exit(void);
void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata);
#else
static inline void ieee80211_debugfs_add_netdev(
struct ieee80211_sub_if_data *sdata)
......@@ -15,10 +14,8 @@ static inline void ieee80211_debugfs_add_netdev(
static inline void ieee80211_debugfs_remove_netdev(
struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_netdev_init(void)
{}
static inline void ieee80211_debugfs_netdev_exit(void)
static inline void ieee80211_debugfs_rename_netdev(
struct ieee80211_sub_if_data *sdata)
{}
#endif
......
......@@ -44,7 +44,7 @@ static const struct file_operations sta_ ##name## _ops = { \
STA_OPS(name)
STA_FILE(aid, sta.aid, D);
STA_FILE(dev, sdata->dev->name, S);
STA_FILE(dev, sdata->name, S);
STA_FILE(rx_packets, rx_packets, LU);
STA_FILE(tx_packets, tx_packets, LU);
STA_FILE(rx_bytes, rx_bytes, LU);
......
......@@ -39,7 +39,7 @@ static inline int drv_add_interface(struct ieee80211_local *local,
struct ieee80211_if_init_conf *conf)
{
int ret = local->ops->add_interface(&local->hw, conf);
trace_drv_add_interface(local, conf->mac_addr, conf->vif, ret);
trace_drv_add_interface(local, conf->vif, ret);
return ret;
}
......@@ -47,7 +47,7 @@ static inline void drv_remove_interface(struct ieee80211_local *local,
struct ieee80211_if_init_conf *conf)
{
local->ops->remove_interface(&local->hw, conf);
trace_drv_remove_interface(local, conf->mac_addr, conf->vif);
trace_drv_remove_interface(local, conf->vif);
}
static inline int drv_config(struct ieee80211_local *local, u32 changed)
......
......@@ -70,11 +70,10 @@ TRACE_EVENT(drv_stop,
TRACE_EVENT(drv_add_interface,
TP_PROTO(struct ieee80211_local *local,
const u8 *addr,
struct ieee80211_vif *vif,
int ret),
TP_ARGS(local, addr, vif, ret),
TP_ARGS(local, vif, ret),
TP_STRUCT__entry(
LOCAL_ENTRY
......@@ -86,7 +85,7 @@ TRACE_EVENT(drv_add_interface,
TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
memcpy(__entry->addr, addr, 6);
memcpy(__entry->addr, vif->addr, 6);
__entry->ret = ret;
),
......@@ -97,10 +96,9 @@ TRACE_EVENT(drv_add_interface,
);
TRACE_EVENT(drv_remove_interface,
TP_PROTO(struct ieee80211_local *local,
const u8 *addr, struct ieee80211_vif *vif),
TP_PROTO(struct ieee80211_local *local, struct ieee80211_vif *vif),
TP_ARGS(local, addr, vif),
TP_ARGS(local, vif),
TP_STRUCT__entry(
LOCAL_ENTRY
......@@ -111,7 +109,7 @@ TRACE_EVENT(drv_remove_interface,
TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
memcpy(__entry->addr, addr, 6);
memcpy(__entry->addr, vif->addr, 6);
),
TP_printk(
......
......@@ -106,7 +106,7 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
if (!skb) {
printk(KERN_ERR "%s: failed to allocate buffer "
"for delba frame\n", sdata->dev->name);
"for delba frame\n", sdata->name);
return;
}
......@@ -114,10 +114,10 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
memset(mgmt, 0, 24);
memcpy(mgmt->da, da, ETH_ALEN);
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
if (sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
......
......@@ -117,7 +117,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_PROBE_RESP);
memset(mgmt->da, 0xff, ETH_ALEN);
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int);
mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
......@@ -266,7 +266,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: updated supp_rates set "
"for %pM based on beacon info (0x%llx | "
"0x%llx -> 0x%llx)\n",
sdata->dev->name,
sdata->name,
sta->sta.addr,
(unsigned long long) prev_rates,
(unsigned long long) supp_rates,
......@@ -364,7 +364,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "%s: beacon TSF higher than "
"local TSF - IBSS merge with BSSID %pM\n",
sdata->dev->name, mgmt->bssid);
sdata->name, mgmt->bssid);
#endif
ieee80211_sta_join_ibss(sdata, bss);
ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
......@@ -393,7 +393,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
sdata->dev->name, addr);
sdata->name, addr);
return NULL;
}
......@@ -402,7 +402,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n",
wiphy_name(local->hw.wiphy), addr, sdata->dev->name);
wiphy_name(local->hw.wiphy), addr, sdata->name);
#endif
sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
......@@ -466,7 +466,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
return;
printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
"IBSS networks with same SSID (merge)\n", sdata->dev->name);
"IBSS networks with same SSID (merge)\n", sdata->name);
ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
}
......@@ -488,13 +488,13 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
* random number generator get different BSSID. */
get_random_bytes(bssid, ETH_ALEN);
for (i = 0; i < ETH_ALEN; i++)
bssid[i] ^= sdata->dev->dev_addr[i];
bssid[i] ^= sdata->vif.addr[i];
bssid[0] &= ~0x01;
bssid[0] |= 0x02;
}
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
sdata->dev->name, bssid);
sdata->name, bssid);
sband = local->hw.wiphy->bands[ifibss->channel->band];
......@@ -523,7 +523,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
active_ibss = ieee80211_sta_active_ibss(sdata);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
sdata->dev->name, active_ibss);
sdata->name, active_ibss);
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (active_ibss)
......@@ -552,7 +552,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
" based on configured SSID\n",
sdata->dev->name, bss->cbss.bssid);
sdata->name, bss->cbss.bssid);
ieee80211_sta_join_ibss(sdata, bss);
ieee80211_rx_bss_put(local, bss);
......@@ -571,7 +571,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
} else if (time_after(jiffies, ifibss->last_scan_completed +
IEEE80211_SCAN_INTERVAL)) {
printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
"join\n", sdata->dev->name);
"join\n", sdata->name);
ieee80211_request_internal_scan(sdata, ifibss->ssid,
ifibss->ssid_len);
......@@ -585,7 +585,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
return;
}
printk(KERN_DEBUG "%s: IBSS not allowed on"
" %d MHz\n", sdata->dev->name,
" %d MHz\n", sdata->name,
local->hw.conf.channel->center_freq);
/* No IBSS found - decrease scan interval and continue
......@@ -619,7 +619,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
" (tx_last_beacon=%d)\n",
sdata->dev->name, mgmt->sa, mgmt->da,
sdata->name, mgmt->sa, mgmt->da,
mgmt->bssid, tx_last_beacon);
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
......@@ -637,7 +637,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
"from %pM\n",
sdata->dev->name, mgmt->sa);
sdata->name, mgmt->sa);
#endif
return;
}
......@@ -657,7 +657,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
memcpy(resp->da, mgmt->sa, ETH_ALEN);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n",
sdata->dev->name, resp->da);
sdata->name, resp->da);
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
ieee80211_tx_skb(sdata, skb);
......@@ -671,7 +671,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
size_t baselen;
struct ieee802_11_elems elems;
if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
return; /* ignore ProbeResp to foreign address */
baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
......
......@@ -140,7 +140,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result;
struct ieee80211_tx_data {
struct sk_buff *skb;
struct net_device *dev;
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
struct sta_info *sta;
......@@ -433,6 +432,8 @@ struct ieee80211_sub_if_data {
int drop_unencrypted;
char name[IFNAMSIZ];
/*
* keep track of whether the HT opmode (stored in
* vif.bss_info.ht_operation_mode) is valid.
......@@ -937,6 +938,8 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,
struct ieee80211_bss *bss);
/* interface handling */
int ieee80211_iface_init(void);
void ieee80211_iface_exit(void);
int ieee80211_if_add(struct ieee80211_local *local, const char *name,
struct net_device **new_dev, enum nl80211_iftype type,
struct vif_params *params);
......
......@@ -60,6 +60,22 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
static int ieee80211_change_mac(struct net_device *dev, void *addr)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int ret;
if (netif_running(dev))
return -EBUSY;
ret = eth_mac_addr(dev, addr);
if (ret == 0)
memcpy(sdata->vif.addr, addr, ETH_ALEN);
return ret;
}
static inline int identical_mac_addr_allowed(int type1, int type2)
{
return type1 == NL80211_IFTYPE_MONITOR ||
......@@ -234,7 +250,7 @@ static int ieee80211_open(struct net_device *dev)
default:
conf.vif = &sdata->vif;
conf.type = sdata->vif.type;
conf.mac_addr = dev->dev_addr;
conf.mac_addr = sdata->vif.addr;
res = drv_add_interface(local, &conf);
if (res)
goto err_stop;
......@@ -514,7 +530,7 @@ static int ieee80211_stop(struct net_device *dev)
conf.vif = &sdata->vif;
conf.type = sdata->vif.type;
conf.mac_addr = dev->dev_addr;
conf.mac_addr = sdata->vif.addr;
/* disable all keys for as long as this netdev is down */
ieee80211_disable_keys(sdata);
drv_remove_interface(local, &conf);
......@@ -651,7 +667,7 @@ static const struct net_device_ops ieee80211_dataif_ops = {
.ndo_start_xmit = ieee80211_subif_start_xmit,
.ndo_set_multicast_list = ieee80211_set_multicast_list,
.ndo_change_mtu = ieee80211_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_set_mac_address = ieee80211_change_mac,
};
static const struct net_device_ops ieee80211_monitorif_ops = {
......@@ -794,6 +810,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
/* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
sdata = netdev_priv(ndev);
ndev->ieee80211_ptr = &sdata->wdev;
memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN);
memcpy(sdata->name, ndev->name, IFNAMSIZ);
/* initialise type-independent data */
sdata->wdev.wiphy = local->hw.wiphy;
......@@ -945,3 +963,41 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
if (chg)
ieee80211_hw_config(local, chg);
}
static int netdev_notify(struct notifier_block *nb,
unsigned long state,
void *ndev)
{
struct net_device *dev = ndev;
struct ieee80211_sub_if_data *sdata;
if (state != NETDEV_CHANGENAME)
return 0;
if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
return 0;
if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
return 0;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
memcpy(sdata->name, sdata->name, IFNAMSIZ);
ieee80211_debugfs_rename_netdev(sdata);
return 0;
}
static struct notifier_block mac80211_netdev_notifier = {
.notifier_call = netdev_notify,
};
int ieee80211_iface_init(void)
{
return register_netdevice_notifier(&mac80211_netdev_notifier);
}
void ieee80211_iface_exit(void)
{
unregister_netdevice_notifier(&mac80211_netdev_notifier);
}
......@@ -32,7 +32,6 @@
#include "led.h"
#include "cfg.h"
#include "debugfs.h"
#include "debugfs_netdev.h"
void ieee80211_configure_filter(struct ieee80211_local *local)
{
......@@ -173,7 +172,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
else if (sdata->vif.type == NL80211_IFTYPE_AP)
sdata->vif.bss_conf.bssid = sdata->dev->dev_addr;
sdata->vif.bss_conf.bssid = sdata->vif.addr;
else if (ieee80211_vif_is_mesh(&sdata->vif)) {
sdata->vif.bss_conf.bssid = zero;
} else {
......@@ -672,11 +671,19 @@ static int __init ieee80211_init(void)
ret = rc80211_pid_init();
if (ret)
return ret;
goto err_pid;
ieee80211_debugfs_netdev_init();
ret = ieee80211_iface_init();
if (ret)
goto err_netdev;
return 0;
err_netdev:
rc80211_pid_exit();
err_pid:
rc80211_minstrel_exit();
return ret;
}
static void __exit ieee80211_exit(void)
......@@ -693,7 +700,7 @@ static void __exit ieee80211_exit(void)
if (mesh_allocated)
ieee80211s_stop();
ieee80211_debugfs_netdev_exit();
ieee80211_iface_exit();
}
......
......@@ -457,7 +457,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: running mesh housekeeping\n",
sdata->dev->name);
sdata->name);
#endif
ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
......@@ -565,7 +565,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
/* ignore ProbeResp to foreign address */
if (stype == IEEE80211_STYPE_PROBE_RESP &&
compare_ether_addr(mgmt->da, sdata->dev->dev_addr))
compare_ether_addr(mgmt->da, sdata->vif.addr))
return;
baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
......
......@@ -128,9 +128,9 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
IEEE80211_STYPE_ACTION);
memcpy(mgmt->da, da, ETH_ALEN);
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
/* BSSID == SA */