summaryrefslogtreecommitdiff
path: root/target/linux/brcm47xx/patches-3.6/720-eth-backport.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm47xx/patches-3.6/720-eth-backport.patch')
-rw-r--r--target/linux/brcm47xx/patches-3.6/720-eth-backport.patch94
1 files changed, 94 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.6/720-eth-backport.patch b/target/linux/brcm47xx/patches-3.6/720-eth-backport.patch
new file mode 100644
index 0000000..98da18a
--- /dev/null
+++ b/target/linux/brcm47xx/patches-3.6/720-eth-backport.patch
@@ -0,0 +1,94 @@
+commit fa0879e37b59e8e3f130a30a9e6fa515717c5bdd
+Author: Stefan Hajnoczi <stefanha@gmail.com>
+Date: Mon Jan 21 01:17:22 2013 +0000
+
+ net: split eth_mac_addr for better error handling
+
+ When we set mac address, software mac address in system and hardware mac
+ address all need to be updated. Current eth_mac_addr() doesn't allow
+ callers to implement error handling nicely.
+
+ This patch split eth_mac_addr() to prepare part and real commit part,
+ then we can prepare first, and try to change hardware address, then do
+ the real commit if hardware address is set successfully.
+
+ Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
+ Signed-off-by: Amos Kong <akong@redhat.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+--- a/include/linux/etherdevice.h
++++ b/include/linux/etherdevice.h
+@@ -40,6 +40,8 @@ extern int eth_header_cache(const struct
+ extern void eth_header_cache_update(struct hh_cache *hh,
+ const struct net_device *dev,
+ const unsigned char *haddr);
++extern int eth_prepare_mac_addr_change(struct net_device *dev, void *p);
++extern void eth_commit_mac_addr_change(struct net_device *dev, void *p);
+ extern int eth_mac_addr(struct net_device *dev, void *p);
+ extern int eth_change_mtu(struct net_device *dev, int new_mtu);
+ extern int eth_validate_addr(struct net_device *dev);
+--- a/net/ethernet/eth.c
++++ b/net/ethernet/eth.c
+@@ -278,16 +278,11 @@ void eth_header_cache_update(struct hh_c
+ EXPORT_SYMBOL(eth_header_cache_update);
+
+ /**
+- * eth_mac_addr - set new Ethernet hardware address
++ * eth_prepare_mac_addr_change - prepare for mac change
+ * @dev: network device
+ * @p: socket address
+- *
+- * Change hardware address of device.
+- *
+- * This doesn't change hardware matching, so needs to be overridden
+- * for most real devices.
+ */
+-int eth_mac_addr(struct net_device *dev, void *p)
++int eth_prepare_mac_addr_change(struct net_device *dev, void *p)
+ {
+ struct sockaddr *addr = p;
+
+@@ -295,9 +290,43 @@ int eth_mac_addr(struct net_device *dev,
+ return -EBUSY;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
++ return 0;
++}
++EXPORT_SYMBOL(eth_prepare_mac_addr_change);
++
++/**
++ * eth_commit_mac_addr_change - commit mac change
++ * @dev: network device
++ * @p: socket address
++ */
++void eth_commit_mac_addr_change(struct net_device *dev, void *p)
++{
++ struct sockaddr *addr = p;
++
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ /* if device marked as NET_ADDR_RANDOM, reset it */
+ dev->addr_assign_type &= ~NET_ADDR_RANDOM;
++}
++EXPORT_SYMBOL(eth_commit_mac_addr_change);
++
++/**
++ * eth_mac_addr - set new Ethernet hardware address
++ * @dev: network device
++ * @p: socket address
++ *
++ * Change hardware address of device.
++ *
++ * This doesn't change hardware matching, so needs to be overridden
++ * for most real devices.
++ */
++int eth_mac_addr(struct net_device *dev, void *p)
++{
++ int ret;
++
++ ret = eth_prepare_mac_addr_change(dev, p);
++ if (ret < 0)
++ return ret;
++ eth_commit_mac_addr_change(dev, p);
+ return 0;
+ }
+ EXPORT_SYMBOL(eth_mac_addr);