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: Luis Carlos Cobo <luisca@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
4eb2ae9a42
commit
bdbe819540
1 changed files with 38 additions and 0 deletions
|
@ -187,9 +187,15 @@ static int ieee80211_open(struct net_device *dev)
|
|||
u32 changed = 0;
|
||||
int res;
|
||||
bool need_hw_reconfig = 0;
|
||||
u8 null_addr[ETH_ALEN] = {0};
|
||||
|
||||
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 */
|
||||
list_for_each_entry(nsdata, &local->interfaces, list) {
|
||||
struct net_device *ndev = nsdata->dev;
|
||||
|
@ -270,6 +276,36 @@ static int ieee80211_open(struct net_device *dev)
|
|||
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) {
|
||||
case IEEE80211_IF_TYPE_VLAN:
|
||||
/* no need to tell driver */
|
||||
|
@ -975,6 +1011,8 @@ void ieee80211_if_setup(struct net_device *dev)
|
|||
dev->open = ieee80211_open;
|
||||
dev->stop = ieee80211_stop;
|
||||
dev->destructor = free_netdev;
|
||||
/* we will validate the address ourselves in ->open */
|
||||
dev->validate_addr = NULL;
|
||||
}
|
||||
|
||||
/* everything else */
|
||||
|
|
Loading…
Reference in a new issue