aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLuis Carlos Cobo <luisca@cozybit.com>2008-08-14 13:40:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-22 16:29:55 -0400
commitbdbe819540f3365249095692118dbfeee308140d (patch)
tree06aedcf13b0003860eedef03785db6977921a67d /net
parent4eb2ae9a42b77de48ee9fecfaccc66c640313188 (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/main.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index f5537f90dd36..93dcdc27254b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -187,9 +187,15 @@ static int ieee80211_open(struct net_device *dev)
187 u32 changed = 0; 187 u32 changed = 0;
188 int res; 188 int res;
189 bool need_hw_reconfig = 0; 189 bool need_hw_reconfig = 0;
190 u8 null_addr[ETH_ALEN] = {0};
190 191
191 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 192 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
192 193
194 /* fail early if user set an invalid address */
195 if (compare_ether_addr(dev->dev_addr, null_addr) &&
196 !is_valid_ether_addr(dev->dev_addr))
197 return -EADDRNOTAVAIL;
198
193 /* we hold the RTNL here so can safely walk the list */ 199 /* we hold the RTNL here so can safely walk the list */
194 list_for_each_entry(nsdata, &local->interfaces, list) { 200 list_for_each_entry(nsdata, &local->interfaces, list) {
195 struct net_device *ndev = nsdata->dev; 201 struct net_device *ndev = nsdata->dev;
@@ -270,6 +276,36 @@ static int ieee80211_open(struct net_device *dev)
270 ieee80211_led_radio(local, local->hw.conf.radio_enabled); 276 ieee80211_led_radio(local, local->hw.conf.radio_enabled);
271 } 277 }
272 278
279 /*
280 * Check all interfaces and copy the hopefully now-present
281 * MAC address to those that have the special null one.
282 */
283 list_for_each_entry(nsdata, &local->interfaces, list) {
284 struct net_device *ndev = nsdata->dev;
285
286 /*
287 * No need to check netif_running since we do not allow
288 * it to start up with this invalid address.
289 */
290 if (compare_ether_addr(null_addr, ndev->dev_addr) == 0)
291 memcpy(ndev->dev_addr,
292 local->hw.wiphy->perm_addr,
293 ETH_ALEN);
294 }
295
296 if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0)
297 memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr,
298 ETH_ALEN);
299
300 /*
301 * Validate the MAC address for this device.
302 */
303 if (!is_valid_ether_addr(dev->dev_addr)) {
304 if (!local->open_count && local->ops->stop)
305 local->ops->stop(local_to_hw(local));
306 return -EADDRNOTAVAIL;
307 }
308
273 switch (sdata->vif.type) { 309 switch (sdata->vif.type) {
274 case IEEE80211_IF_TYPE_VLAN: 310 case IEEE80211_IF_TYPE_VLAN:
275 /* no need to tell driver */ 311 /* no need to tell driver */
@@ -975,6 +1011,8 @@ void ieee80211_if_setup(struct net_device *dev)
975 dev->open = ieee80211_open; 1011 dev->open = ieee80211_open;
976 dev->stop = ieee80211_stop; 1012 dev->stop = ieee80211_stop;
977 dev->destructor = free_netdev; 1013 dev->destructor = free_netdev;
1014 /* we will validate the address ourselves in ->open */
1015 dev->validate_addr = NULL;
978} 1016}
979 1017
980/* everything else */ 1018/* everything else */