Commit bdbe8195 authored by Luis Carlos Cobo's avatar Luis Carlos Cobo Committed by John W. Linville

mac80211: allow no mac address until firmware load

Originally by Johannes Berg. This patch adds support for devices that do not
report their MAC address until the firmware is loaded. While the address is not
known, a multicast on is used.
Signed-off-by: default avatarLuis Carlos Cobo <luisca@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4eb2ae9a
...@@ -187,9 +187,15 @@ static int ieee80211_open(struct net_device *dev) ...@@ -187,9 +187,15 @@ static int ieee80211_open(struct net_device *dev)
u32 changed = 0; u32 changed = 0;
int res; int res;
bool need_hw_reconfig = 0; bool need_hw_reconfig = 0;
u8 null_addr[ETH_ALEN] = {0};
sdata = IEEE80211_DEV_TO_SUB_IF(dev); sdata = IEEE80211_DEV_TO_SUB_IF(dev);
/* fail early if user set an invalid address */
if (compare_ether_addr(dev->dev_addr, null_addr) &&
!is_valid_ether_addr(dev->dev_addr))
return -EADDRNOTAVAIL;
/* we hold the RTNL here so can safely walk the list */ /* we hold the RTNL here so can safely walk the list */
list_for_each_entry(nsdata, &local->interfaces, list) { list_for_each_entry(nsdata, &local->interfaces, list) {
struct net_device *ndev = nsdata->dev; struct net_device *ndev = nsdata->dev;
...@@ -270,6 +276,36 @@ static int ieee80211_open(struct net_device *dev) ...@@ -270,6 +276,36 @@ static int ieee80211_open(struct net_device *dev)
ieee80211_led_radio(local, local->hw.conf.radio_enabled); ieee80211_led_radio(local, local->hw.conf.radio_enabled);
} }
/*
* Check all interfaces and copy the hopefully now-present
* MAC address to those that have the special null one.
*/
list_for_each_entry(nsdata, &local->interfaces, list) {
struct net_device *ndev = nsdata->dev;
/*
* 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)
memcpy(ndev->dev_addr,
local->hw.wiphy->perm_addr,
ETH_ALEN);
}
if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0)
memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr,
ETH_ALEN);
/*
* Validate the MAC address for this device.
*/
if (!is_valid_ether_addr(dev->dev_addr)) {
if (!local->open_count && local->ops->stop)
local->ops->stop(local_to_hw(local));
return -EADDRNOTAVAIL;
}
switch (sdata->vif.type) { switch (sdata->vif.type) {
case IEEE80211_IF_TYPE_VLAN: case IEEE80211_IF_TYPE_VLAN:
/* no need to tell driver */ /* no need to tell driver */
...@@ -975,6 +1011,8 @@ void ieee80211_if_setup(struct net_device *dev) ...@@ -975,6 +1011,8 @@ void ieee80211_if_setup(struct net_device *dev)
dev->open = ieee80211_open; dev->open = ieee80211_open;
dev->stop = ieee80211_stop; dev->stop = ieee80211_stop;
dev->destructor = free_netdev; dev->destructor = free_netdev;
/* we will validate the address ourselves in ->open */
dev->validate_addr = NULL;
} }
/* everything else */ /* everything else */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment