diff options
Diffstat (limited to 'target/linux/brcm47xx')
| -rw-r--r-- | target/linux/brcm47xx/patches-3.6/720-eth-backport.patch | 94 | ||||
| -rw-r--r-- | target/linux/brcm47xx/patches-3.6/760-bgmac-fixes.patch | 112 | 
2 files changed, 206 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 000000000..98da18a3b --- /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); diff --git a/target/linux/brcm47xx/patches-3.6/760-bgmac-fixes.patch b/target/linux/brcm47xx/patches-3.6/760-bgmac-fixes.patch new file mode 100644 index 000000000..dfe9ccf7e --- /dev/null +++ b/target/linux/brcm47xx/patches-3.6/760-bgmac-fixes.patch @@ -0,0 +1,112 @@ +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -761,6 +761,26 @@ static void bgmac_cmdcfg_maskset(struct + 	udelay(2); + } +  ++static void bgmac_write_mac_address(struct bgmac *bgmac, u8 *addr) ++{ ++	u32 tmp; ++ ++	tmp = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; ++	bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp); ++	tmp = (addr[4] << 8) | addr[5]; ++	bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp); ++} ++ ++static void bgmac_set_rx_mode(struct net_device *net_dev) ++{ ++	struct bgmac *bgmac = netdev_priv(net_dev); ++ ++	if (net_dev->flags & IFF_PROMISC) ++		bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, false); ++	else ++		bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, false); ++} ++ + #if 0 /* We don't use that regs yet */ + static void bgmac_chip_stats_update(struct bgmac *bgmac) + { +@@ -889,8 +909,10 @@ static void bgmac_chip_reset(struct bgma + 			sw_type = et_swtype; + 		} else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 9) { + 			sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII; +-		} else if (0) { +-			/* TODO */ ++		} else if ((ci->id != BCMA_CHIP_ID_BCM53572 && ci->pkg == 10) || ++			   (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == 9)) { ++			sw_type = BGMAC_CHIPCTL_1_IF_TYPE_RGMII | ++				  BGMAC_CHIPCTL_1_SW_TYPE_RGMII; + 		} + 		bcma_chipco_chipctl_maskset(cc, 1, + 					    ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK | +@@ -1004,8 +1026,6 @@ static void bgmac_enable(struct bgmac *b + static void bgmac_chip_init(struct bgmac *bgmac, bool full_init) + { + 	struct bgmac_dma_ring *ring; +-	u8 *mac = bgmac->net_dev->dev_addr; +-	u32 tmp; + 	int i; +  + 	/* 1 interrupt per received frame */ +@@ -1014,16 +1034,9 @@ static void bgmac_chip_init(struct bgmac + 	/* Enable 802.3x tx flow control (honor received PAUSE frames) */ + 	bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true); +  +-	if (bgmac->net_dev->flags & IFF_PROMISC) +-		bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, false); +-	else +-		bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, false); ++	bgmac_set_rx_mode(bgmac->net_dev); +  +-	/* Set MAC addr */ +-	tmp = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3]; +-	bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp); +-	tmp = (mac[4] << 8) | mac[5]; +-	bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp); ++	bgmac_write_mac_address(bgmac, bgmac->net_dev->dev_addr); +  + 	if (bgmac->loopback) + 		bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, true); +@@ -1160,6 +1173,19 @@ static netdev_tx_t bgmac_start_xmit(stru + 	return bgmac_dma_tx_add(bgmac, ring, skb); + } +  ++static int bgmac_set_mac_address(struct net_device *net_dev, void *addr) ++{ ++	struct bgmac *bgmac = netdev_priv(net_dev); ++	int ret; ++ ++	ret = eth_prepare_mac_addr_change(net_dev, addr); ++	if (ret < 0) ++		return ret; ++	bgmac_write_mac_address(bgmac, (u8 *)addr); ++	eth_commit_mac_addr_change(net_dev, addr); ++	return 0; ++} ++ + static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) + { + 	struct bgmac *bgmac = netdev_priv(net_dev); +@@ -1190,7 +1216,9 @@ static const struct net_device_ops bgmac + 	.ndo_open		= bgmac_open, + 	.ndo_stop		= bgmac_stop, + 	.ndo_start_xmit		= bgmac_start_xmit, +-	.ndo_set_mac_address	= eth_mac_addr, /* generic, sets dev_addr */ ++	.ndo_set_rx_mode	= bgmac_set_rx_mode, ++	.ndo_set_mac_address	= bgmac_set_mac_address, ++	.ndo_validate_addr	= eth_validate_addr, + 	.ndo_do_ioctl           = bgmac_ioctl, + }; +  +--- a/drivers/net/ethernet/broadcom/bgmac.h ++++ b/drivers/net/ethernet/broadcom/bgmac.h +@@ -339,7 +339,7 @@ + #define BGMAC_CHIPCTL_1_SW_TYPE_EPHY		0x00000000 + #define BGMAC_CHIPCTL_1_SW_TYPE_EPHYMII		0x00000040 + #define BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII	0x00000080 +-#define BGMAC_CHIPCTL_1_SW_TYPE_RGMI		0x000000C0 ++#define BGMAC_CHIPCTL_1_SW_TYPE_RGMII		0x000000C0 + #define BGMAC_CHIPCTL_1_RXC_DLL_BYPASS		0x00010000 +  + #define BGMAC_SPEED_10				0x0001  | 
