diff options
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/designware.c | 2 | ||||
| -rw-r--r-- | drivers/net/designware.h | 7 | ||||
| -rw-r--r-- | drivers/net/dm9000x.c | 9 | ||||
| -rw-r--r-- | drivers/net/e1000.c | 34 | ||||
| -rw-r--r-- | drivers/net/e1000.h | 9 | ||||
| -rw-r--r-- | drivers/net/fm/Makefile | 7 | ||||
| -rw-r--r-- | drivers/net/fm/eth.c | 12 | ||||
| -rw-r--r-- | drivers/net/fm/fm.h | 2 | ||||
| -rw-r--r-- | drivers/net/fm/init.c | 18 | ||||
| -rw-r--r-- | drivers/net/fm/t2080.c | 91 | ||||
| -rw-r--r-- | drivers/net/fsl_mdio.c | 17 | ||||
| -rw-r--r-- | drivers/net/mvgbe.c | 5 | ||||
| -rw-r--r-- | drivers/net/npe/Makefile | 3 | ||||
| -rw-r--r-- | drivers/net/pcnet.c | 277 | ||||
| -rw-r--r-- | drivers/net/phy/atheros.c | 8 | ||||
| -rw-r--r-- | drivers/net/phy/micrel.c | 34 | ||||
| -rw-r--r-- | drivers/net/phy/phy.c | 5 | ||||
| -rw-r--r-- | drivers/net/phy/realtek.c | 6 | ||||
| -rw-r--r-- | drivers/net/phy/smsc.c | 3 | ||||
| -rw-r--r-- | drivers/net/phy/vitesse.c | 69 | ||||
| -rw-r--r-- | drivers/net/rtl8139.c | 2 | ||||
| -rw-r--r-- | drivers/net/rtl8169.c | 90 | ||||
| -rw-r--r-- | drivers/net/sh_eth.c | 51 | ||||
| -rw-r--r-- | drivers/net/sh_eth.h | 34 | ||||
| -rw-r--r-- | drivers/net/tsec.c | 193 | ||||
| -rw-r--r-- | drivers/net/zynq_gem.c | 82 | 
26 files changed, 741 insertions, 329 deletions
| diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 8413d5776..22155b4d9 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -96,7 +96,7 @@ static int mac_reset(struct eth_device *dev)  	ulong start;  	int timeout = CONFIG_MACRESET_TIMEOUT; -	writel(DMAMAC_SRST, &dma_p->busmode); +	writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);  	if (priv->interface != PHY_INTERFACE_MODE_RGMII)  		writel(MII_PORTSELECT, &mac_p->conf); diff --git a/drivers/net/designware.h b/drivers/net/designware.h index e80002a0e..5440c9215 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -112,7 +112,7 @@ struct dmamacdescr {  	u32 dmamac_cntl;  	void *dmamac_addr;  	struct dmamacdescr *dmamac_next; -}; +} __aligned(16);  /*   * txrx_status definitions @@ -224,8 +224,7 @@ struct dw_eth_dev {  	u32 tx_currdescnum;  	u32 rx_currdescnum;  	u32 phy_configured; -	int link_printed; -	u32 padding; +	u32 link_printed;  	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];  	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; @@ -237,7 +236,7 @@ struct dw_eth_dev {  	struct eth_dma_regs *dma_regs_p;  	struct eth_device *dev; -} __attribute__ ((aligned(8))); +};  /* Speed specific definitions */  #define SPEED_10M		1 diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index f7170e055..b68d808c7 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -342,6 +342,15 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd)  	DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);  	printf("MAC: %pM\n", dev->enetaddr); +	if (!is_valid_ether_addr(dev->enetaddr)) { +#ifdef CONFIG_RANDOM_MACADDR +		printf("Bad MAC address (uninitialized EEPROM?), randomizing\n"); +		eth_random_enetaddr(dev->enetaddr); +		printf("MAC: %pM\n", dev->enetaddr); +#else +		printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n"); +#endif +	}  	/* fill device MAC address registers */  	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 57aa53dba..9a66e68ae 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -114,12 +114,13 @@ static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,  static int32_t e1000_phy_hw_reset(struct e1000_hw *hw);  static int e1000_phy_reset(struct e1000_hw *hw);  static int e1000_detect_gig_phy(struct e1000_hw *hw); -static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);  static void e1000_set_media_type(struct e1000_hw *hw);  static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);  static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); +#ifndef CONFIG_E1000_NO_NVM +static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);  static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,  		uint16_t words,  		uint16_t *data); @@ -885,6 +886,7 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw)  	return -E1000_ERR_EEPROM;  } +#endif /* CONFIG_E1000_NO_NVM */  /*****************************************************************************   * Set PHY to class A mode @@ -897,6 +899,7 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw)  static int32_t  e1000_set_phy_mode(struct e1000_hw *hw)  { +#ifndef CONFIG_E1000_NO_NVM  	int32_t ret_val;  	uint16_t eeprom_data; @@ -923,10 +926,11 @@ e1000_set_phy_mode(struct e1000_hw *hw)  			hw->phy_reset_disable = false;  		}  	} - +#endif  	return E1000_SUCCESS;  } +#ifndef CONFIG_E1000_NO_NVM  /***************************************************************************   *   * Obtaining software semaphore bit (SMBI) before resetting PHY. @@ -965,6 +969,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw)  	return E1000_SUCCESS;  } +#endif  /***************************************************************************   * This function clears HW semaphore bits. @@ -977,6 +982,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw)  static void  e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)  { +#ifndef CONFIG_E1000_NO_NVM  	 uint32_t swsm;  	DEBUGFUNC(); @@ -991,6 +997,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)  	} else  		swsm &= ~(E1000_SWSM_SWESMBI);  	E1000_WRITE_REG(hw, SWSM, swsm); +#endif  }  /*************************************************************************** @@ -1007,6 +1014,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)  static int32_t  e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)  { +#ifndef CONFIG_E1000_NO_NVM  	int32_t timeout;  	uint32_t swsm; @@ -1043,7 +1051,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)  				"SWESMBI bit is set.\n");  		return -E1000_ERR_EEPROM;  	} - +#endif  	return E1000_SUCCESS;  } @@ -1097,6 +1105,7 @@ static bool e1000_is_second_port(struct e1000_hw *hw)  	}  } +#ifndef CONFIG_E1000_NO_NVM  /******************************************************************************   * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the   * second function of dual function devices @@ -1136,6 +1145,7 @@ e1000_read_mac_addr(struct eth_device *nic)  #endif  	return 0;  } +#endif  /******************************************************************************   * Initializes receive address filters. @@ -1764,9 +1774,11 @@ static int  e1000_setup_link(struct eth_device *nic)  {  	struct e1000_hw *hw = nic->priv; -	uint32_t ctrl_ext;  	int32_t ret_val; +#ifndef CONFIG_E1000_NO_NVM +	uint32_t ctrl_ext;  	uint16_t eeprom_data; +#endif  	DEBUGFUNC(); @@ -1775,6 +1787,7 @@ e1000_setup_link(struct eth_device *nic)  	if (e1000_check_phy_reset_block(hw))  		return E1000_SUCCESS; +#ifndef CONFIG_E1000_NO_NVM  	/* Read and store word 0x0F of the EEPROM. This word contains bits  	 * that determine the hardware's default PAUSE (flow control) mode,  	 * a bit that determines whether the HW defaults to enabling or @@ -1788,7 +1801,7 @@ e1000_setup_link(struct eth_device *nic)  		DEBUGOUT("EEPROM Read Error\n");  		return -E1000_ERR_EEPROM;  	} - +#endif  	if (hw->fc == e1000_fc_default) {  		switch (hw->mac_type) {  		case e1000_ich8lan: @@ -1797,6 +1810,7 @@ e1000_setup_link(struct eth_device *nic)  			hw->fc = e1000_fc_full;  			break;  		default: +#ifndef CONFIG_E1000_NO_NVM  			ret_val = e1000_read_eeprom(hw,  				EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);  			if (ret_val) { @@ -1809,6 +1823,7 @@ e1000_setup_link(struct eth_device *nic)  				    EEPROM_WORD0F_ASM_DIR)  				hw->fc = e1000_fc_tx_pause;  			else +#endif  				hw->fc = e1000_fc_full;  			break;  		} @@ -1828,6 +1843,7 @@ e1000_setup_link(struct eth_device *nic)  	DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc); +#ifndef CONFIG_E1000_NO_NVM  	/* Take the 4 bits from EEPROM word 0x0F that determine the initial  	 * polarity value for the SW controlled pins, and setup the  	 * Extended Device Control reg with that info. @@ -1840,6 +1856,7 @@ e1000_setup_link(struct eth_device *nic)  			    SWDPIO__EXT_SHIFT);  		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);  	} +#endif  	/* Call the necessary subroutine to configure the link. */  	ret_val = (hw->media_type == e1000_media_type_fiber) ? @@ -5196,6 +5213,7 @@ e1000_initialize(bd_t * bis)  		e1000_reset_hw(hw);  		list_add_tail(&hw->list_node, &e1000_hw_list); +#ifndef CONFIG_E1000_NO_NVM  		/* Validate the EEPROM and get chipset information */  #if !defined(CONFIG_MVBC_1G)  		if (e1000_init_eeprom_params(hw)) { @@ -5206,11 +5224,17 @@ e1000_initialize(bd_t * bis)  			continue;  #endif  		e1000_read_mac_addr(nic); +#endif  		e1000_get_bus_type(hw); +#ifndef CONFIG_E1000_NO_NVM  		printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n       ",  		       nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2],  		       nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]); +#else +		memset(nic->enetaddr, 0, 6); +		printf("e1000: no NVM\n"); +#endif  		/* Set up the function pointers and register the device */  		nic->init = e1000_init; diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 25884f5bc..ff87af2ef 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -63,11 +63,14 @@ struct e1000_hw_stats;  /* Internal E1000 helper functions */  struct e1000_hw *e1000_find_card(unsigned int cardnum); + +#ifndef CONFIG_E1000_NO_NVM  int32_t e1000_acquire_eeprom(struct e1000_hw *hw);  void e1000_standby_eeprom(struct e1000_hw *hw);  void e1000_release_eeprom(struct e1000_hw *hw);  void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);  void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd); +#endif  #ifdef CONFIG_E1000_SPI  int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw, @@ -1019,6 +1022,7 @@ struct e1000_hw_stats {  	uint64_t tsctfc;  }; +#ifndef CONFIG_E1000_NO_NVM  struct e1000_eeprom_info {  e1000_eeprom_type type;  	uint16_t word_size; @@ -1029,6 +1033,7 @@ e1000_eeprom_type type;  	bool use_eerd;  	bool use_eewr;  }; +#endif  typedef enum {      e1000_smart_speed_default = 0, @@ -1081,10 +1086,14 @@ struct e1000_hw {  	uint32_t io_base;  #endif  	uint32_t		asf_firmware_present; +#ifndef CONFIG_E1000_NO_NVM  	uint32_t		eeprom_semaphore_present; +#endif  	uint32_t		swfw_sync_present;  	uint32_t		swfwhw_semaphore_present; +#ifndef CONFIG_E1000_NO_NVM  	struct e1000_eeprom_info eeprom; +#endif  	e1000_ms_type		master_slave;  	e1000_ms_type		original_master_slave;  	e1000_ffe_config	ffe_config_state; diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index bec86c16c..ee5d76893 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -4,7 +4,6 @@  # SPDX-License-Identifier:	GPL-2.0+  # -ifdef CONFIG_FMAN_ENET  obj-y += dtsec.o  obj-y += eth.o  obj-y += fm.o @@ -26,8 +25,12 @@ obj-$(CONFIG_PPC_P4080) += p4080.o  obj-$(CONFIG_PPC_P5020) += p5020.o  obj-$(CONFIG_PPC_P5040) += p5040.o  obj-$(CONFIG_PPC_T1040) += t1040.o +obj-$(CONFIG_PPC_T1042)	+= t1040.o +obj-$(CONFIG_PPC_T1020)	+= t1040.o +obj-$(CONFIG_PPC_T1022)	+= t1040.o +obj-$(CONFIG_PPC_T2080) += t2080.o +obj-$(CONFIG_PPC_T2081) += t2080.o  obj-$(CONFIG_PPC_T4240) += t4240.o  obj-$(CONFIG_PPC_T4160) += t4240.o  obj-$(CONFIG_PPC_B4420) += b4860.o  obj-$(CONFIG_PPC_B4860) += b4860.o -endif diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c index cb099cd84..218a5ed17 100644 --- a/drivers/net/fm/eth.c +++ b/drivers/net/fm/eth.c @@ -557,8 +557,16 @@ static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)  	num = fm_eth->num;  #ifdef CONFIG_SYS_FMAN_V3 -	if (fm_eth->type == FM_ETH_10G_E) -		num += 8; +	if (fm_eth->type == FM_ETH_10G_E) { +		/* 10GEC1/10GEC2 use mEMAC9/mEMAC10 +		 * 10GEC3/10GEC4 use mEMAC1/mEMAC2 +		 * so it needs to change the num. +		 */ +		if (fm_eth->num >= 2) +			num -= 2; +		else +			num += 8; +	}  	base = ®->memac[num].fm_memac;  	phyregs = ®->memac[num].fm_memac_mdio;  #else diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index 3ec49a4f3..43de114b5 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -18,9 +18,11 @@  #define RX_PORT_1G_BASE		0x08  #define MAX_NUM_RX_PORT_1G	CONFIG_SYS_NUM_FM1_DTSEC  #define RX_PORT_10G_BASE	0x10 +#define RX_PORT_10G_BASE2	0x08  #define TX_PORT_1G_BASE		0x28  #define MAX_NUM_TX_PORT_1G	CONFIG_SYS_NUM_FM1_DTSEC  #define TX_PORT_10G_BASE	0x30 +#define TX_PORT_10G_BASE2	0x28  #define MIIM_TIMEOUT    0xFFFF  struct fm_muram { diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 35edd7ad9..cd787f4ee 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -64,6 +64,12 @@ struct fm_eth_info fm_info[] = {  #if (CONFIG_SYS_NUM_FM1_10GEC >= 2)  	FM_TGEC_INFO_INITIALIZER(1, 2),  #endif +#if (CONFIG_SYS_NUM_FM1_10GEC >= 3) +	FM_TGEC_INFO_INITIALIZER2(1, 3), +#endif +#if (CONFIG_SYS_NUM_FM1_10GEC >= 4) +	FM_TGEC_INFO_INITIALIZER2(1, 4), +#endif  #if (CONFIG_SYS_NUM_FM2_10GEC >= 1)  	FM_TGEC_INFO_INITIALIZER(2, 1),  #endif @@ -239,10 +245,14 @@ static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop)  	 * FM1_10GEC1 is enabled and  FM1_DTSEC9 is disabled, ensure that the  	 * dual-role MAC is not disabled, ditto for other dual-role MACs.  	 */ -	if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1)))	|| -	    ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2)))	|| -	    ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9)))	|| -	    ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) +	if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1)))  || +	    ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) || +	    ((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC3)))  || +	    ((info->port == FM1_DTSEC2) && (PORT_IS_ENABLED(FM1_10GEC4)))  || +	    ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9)))  || +	    ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) || +	    ((info->port == FM1_10GEC3) && (PORT_IS_ENABLED(FM1_DTSEC1)))  || +	    ((info->port == FM1_10GEC4) && (PORT_IS_ENABLED(FM1_DTSEC2)))  #if (CONFIG_SYS_NUM_FMAN == 2)  										||  	    ((info->port == FM2_DTSEC9) && (PORT_IS_ENABLED(FM2_10GEC1)))	|| diff --git a/drivers/net/fm/t2080.c b/drivers/net/fm/t2080.c new file mode 100644 index 000000000..b5c1e9f76 --- /dev/null +++ b/drivers/net/fm/t2080.c @@ -0,0 +1,91 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * Shengzhou Liu <Shengzhou.Liu@freescale.com> + * + * SPDX-License-Identifier:     GPL-2.0+ + */ + +#include <common.h> +#include <phy.h> +#include <fm_eth.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_serdes.h> + +u32 port_to_devdisr[] = { +	[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, +	[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, +	[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, +	[FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, +	[FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5, +	[FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6, +	[FM1_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC1_9, +	[FM1_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC1_10, +	[FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1, +	[FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2, +	[FM1_10GEC3] = FSL_CORENET_DEVDISR2_10GEC1_3, +	[FM1_10GEC4] = FSL_CORENET_DEVDISR2_10GEC1_4, +}; + +static int is_device_disabled(enum fm_port port) +{ +	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +	u32 devdisr2 = in_be32(&gur->devdisr2); + +	return port_to_devdisr[port] & devdisr2; +} + +void fman_disable_port(enum fm_port port) +{ +	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + +	setbits_be32(&gur->devdisr2, port_to_devdisr[port]); +} + +phy_interface_t fman_port_enet_if(enum fm_port port) +{ +	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +	u32 rcwsr13 = in_be32(&gur->rcwsr[13]); + +	if (is_device_disabled(port)) +		return PHY_INTERFACE_MODE_NONE; + +	if ((port == FM1_10GEC1 || port == FM1_10GEC2 || +	     port == FM1_10GEC3 || port == FM1_10GEC4) && +	    ((is_serdes_configured(XAUI_FM1_MAC9))	|| +	     (is_serdes_configured(XFI_FM1_MAC1))	|| +	     (is_serdes_configured(XFI_FM1_MAC2))	|| +	     (is_serdes_configured(XFI_FM1_MAC9))	|| +	     (is_serdes_configured(XFI_FM1_MAC10)))) +		return PHY_INTERFACE_MODE_XGMII; + +	if ((port == FM1_DTSEC3) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == +		FSL_CORENET_RCWSR13_EC1_DTSEC3_RGMII)) +		return PHY_INTERFACE_MODE_RGMII; + +	if ((port == FM1_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == +		FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII)) +		return PHY_INTERFACE_MODE_RGMII; + +	if ((port == FM1_DTSEC10) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == +		FSL_CORENET_RCWSR13_EC2_DTSEC10_RGMII)) +		return PHY_INTERFACE_MODE_RGMII; + +	switch (port) { +	case FM1_DTSEC1: +	case FM1_DTSEC2: +	case FM1_DTSEC3: +	case FM1_DTSEC4: +	case FM1_DTSEC5: +	case FM1_DTSEC6: +	case FM1_DTSEC9: +	case FM1_DTSEC10: +		if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) +			return PHY_INTERFACE_MODE_SGMII; +		break; +	default: +		return PHY_INTERFACE_MODE_NONE; +	} + +	return PHY_INTERFACE_MODE_NONE; +} diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c index ce36bd7a3..1d88e6504 100644 --- a/drivers/net/fsl_mdio.c +++ b/drivers/net/fsl_mdio.c @@ -1,5 +1,5 @@  /* - * Copyright 2009-2010 Freescale Semiconductor, Inc. + * Copyright 2009-2010, 2013 Freescale Semiconductor, Inc.   *	Jun-jie Zhang <b18070@freescale.com>   *	Mingkai Hu <Mingkai.hu@freescale.com>   * @@ -13,7 +13,7 @@  #include <asm/errno.h>  #include <asm/fsl_enet.h> -void tsec_local_mdio_write(struct tsec_mii_mng *phyregs, int port_addr, +void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr,  		int dev_addr, int regnum, int value)  {  	int timeout = 1000000; @@ -26,7 +26,7 @@ void tsec_local_mdio_write(struct tsec_mii_mng *phyregs, int port_addr,  		;  } -int tsec_local_mdio_read(struct tsec_mii_mng *phyregs, int port_addr, +int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr,  		int dev_addr, int regnum)  {  	int value; @@ -57,7 +57,8 @@ int tsec_local_mdio_read(struct tsec_mii_mng *phyregs, int port_addr,  static int fsl_pq_mdio_reset(struct mii_dev *bus)  { -	struct tsec_mii_mng *regs = bus->priv; +	struct tsec_mii_mng __iomem *regs = +		(struct tsec_mii_mng __iomem *)bus->priv;  	/* Reset MII (due to new addresses) */  	out_be32(®s->miimcfg, MIIMCFG_RESET_MGMT); @@ -72,7 +73,8 @@ static int fsl_pq_mdio_reset(struct mii_dev *bus)  int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum)  { -	struct tsec_mii_mng *phyregs = bus->priv; +	struct tsec_mii_mng __iomem *phyregs = +		(struct tsec_mii_mng __iomem *)bus->priv;  	return tsec_local_mdio_read(phyregs, addr, dev_addr, regnum);  } @@ -80,7 +82,8 @@ int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum)  int tsec_phy_write(struct mii_dev *bus, int addr, int dev_addr, int regnum,  			u16 value)  { -	struct tsec_mii_mng *phyregs = bus->priv; +	struct tsec_mii_mng __iomem *phyregs = +		(struct tsec_mii_mng __iomem *)bus->priv;  	tsec_local_mdio_write(phyregs, addr, dev_addr, regnum, value); @@ -101,7 +104,7 @@ int fsl_pq_mdio_init(bd_t *bis, struct fsl_pq_mdio_info *info)  	bus->reset = fsl_pq_mdio_reset;  	sprintf(bus->name, info->name); -	bus->priv = info->regs; +	bus->priv = (void *)info->regs;  	return mdio_register(bus);  } diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c index 6c901d1ea..0cd06b6a6 100644 --- a/drivers/net/mvgbe.c +++ b/drivers/net/mvgbe.c @@ -420,8 +420,9 @@ static int mvgbe_init(struct eth_device *dev)  {  	struct mvgbe_device *dmvgbe = to_mvgbe(dev);  	struct mvgbe_registers *regs = dmvgbe->regs; -#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \ -	 && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN) +#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) &&  \ +	!defined(CONFIG_PHYLIB) &&			 \ +	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)  	int i;  #endif  	/* setup RX rings */ diff --git a/drivers/net/npe/Makefile b/drivers/net/npe/Makefile index 7fa5ea635..077925521 100644 --- a/drivers/net/npe/Makefile +++ b/drivers/net/npe/Makefile @@ -8,9 +8,8 @@  LOCAL_CFLAGS  += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux  CFLAGS  += $(LOCAL_CFLAGS)  CPPFLAGS  += $(LOCAL_CFLAGS) # needed for depend -HOSTCFLAGS  += $(LOCAL_CFLAGS) -obj-$(CONFIG_IXP4XX_NPE) := npe.o \ +obj-y := npe.o \  	miiphy.o \  	IxOsalBufferMgt.o \  	IxOsalIoMem.o \ diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 283cb48b4..71a311071 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -89,39 +89,39 @@ static pcnet_priv_t *lp;  #define PCNET_RESET		0x14  #define PCNET_BDP		0x16 -static u16 pcnet_read_csr (struct eth_device *dev, int index) +static u16 pcnet_read_csr(struct eth_device *dev, int index)  { -	outw (index, dev->iobase + PCNET_RAP); -	return inw (dev->iobase + PCNET_RDP); +	outw(index, dev->iobase + PCNET_RAP); +	return inw(dev->iobase + PCNET_RDP);  } -static void pcnet_write_csr (struct eth_device *dev, int index, u16 val) +static void pcnet_write_csr(struct eth_device *dev, int index, u16 val)  { -	outw (index, dev->iobase + PCNET_RAP); -	outw (val, dev->iobase + PCNET_RDP); +	outw(index, dev->iobase + PCNET_RAP); +	outw(val, dev->iobase + PCNET_RDP);  } -static u16 pcnet_read_bcr (struct eth_device *dev, int index) +static u16 pcnet_read_bcr(struct eth_device *dev, int index)  { -	outw (index, dev->iobase + PCNET_RAP); -	return inw (dev->iobase + PCNET_BDP); +	outw(index, dev->iobase + PCNET_RAP); +	return inw(dev->iobase + PCNET_BDP);  } -static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val) +static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val)  { -	outw (index, dev->iobase + PCNET_RAP); -	outw (val, dev->iobase + PCNET_BDP); +	outw(index, dev->iobase + PCNET_RAP); +	outw(val, dev->iobase + PCNET_BDP);  } -static void pcnet_reset (struct eth_device *dev) +static void pcnet_reset(struct eth_device *dev)  { -	inw (dev->iobase + PCNET_RESET); +	inw(dev->iobase + PCNET_RESET);  } -static int pcnet_check (struct eth_device *dev) +static int pcnet_check(struct eth_device *dev)  { -	outw (88, dev->iobase + PCNET_RAP); -	return (inw (dev->iobase + PCNET_RAP) == 88); +	outw(88, dev->iobase + PCNET_RAP); +	return inw(dev->iobase + PCNET_RAP) == 88;  }  static int pcnet_init (struct eth_device *dev, bd_t * bis); @@ -139,63 +139,64 @@ static struct pci_device_id supported[] = {  }; -int pcnet_initialize (bd_t * bis) +int pcnet_initialize(bd_t *bis)  {  	pci_dev_t devbusfn;  	struct eth_device *dev;  	u16 command, status;  	int dev_nr = 0; -	PCNET_DEBUG1 ("\npcnet_initialize...\n"); +	PCNET_DEBUG1("\npcnet_initialize...\n");  	for (dev_nr = 0;; dev_nr++) {  		/*  		 * Find the PCnet PCI device(s).  		 */ -		if ((devbusfn = pci_find_devices (supported, dev_nr)) < 0) { +		devbusfn = pci_find_devices(supported, dev_nr); +		if (devbusfn < 0)  			break; -		}  		/*  		 * Allocate and pre-fill the device structure.  		 */ -		dev = (struct eth_device *) malloc (sizeof *dev); +		dev = (struct eth_device *)malloc(sizeof(*dev));  		if (!dev) {  			printf("pcnet: Can not allocate memory\n");  			break;  		}  		memset(dev, 0, sizeof(*dev)); -		dev->priv = (void *) devbusfn; -		sprintf (dev->name, "pcnet#%d", dev_nr); +		dev->priv = (void *)devbusfn; +		sprintf(dev->name, "pcnet#%d", dev_nr);  		/*  		 * Setup the PCI device.  		 */ -		pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, -				       (unsigned int *) &dev->iobase); -		dev->iobase=pci_io_to_phys (devbusfn, dev->iobase); +		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, +				      (unsigned int *)&dev->iobase); +		dev->iobase = pci_io_to_phys(devbusfn, dev->iobase);  		dev->iobase &= ~0xf; -		PCNET_DEBUG1 ("%s: devbusfn=0x%x iobase=0x%x: ", -			      dev->name, devbusfn, dev->iobase); +		PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ", +			     dev->name, devbusfn, dev->iobase);  		command = PCI_COMMAND_IO | PCI_COMMAND_MASTER; -		pci_write_config_word (devbusfn, PCI_COMMAND, command); -		pci_read_config_word (devbusfn, PCI_COMMAND, &status); +		pci_write_config_word(devbusfn, PCI_COMMAND, command); +		pci_read_config_word(devbusfn, PCI_COMMAND, &status);  		if ((status & command) != command) { -			printf ("%s: Couldn't enable IO access or Bus Mastering\n", dev->name); -			free (dev); +			printf("%s: Couldn't enable IO access or Bus Mastering\n", +			       dev->name); +			free(dev);  			continue;  		} -		pci_write_config_byte (devbusfn, PCI_LATENCY_TIMER, 0x40); +		pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);  		/*  		 * Probe the PCnet chip.  		 */ -		if (pcnet_probe (dev, bis, dev_nr) < 0) { -			free (dev); +		if (pcnet_probe(dev, bis, dev_nr) < 0) { +			free(dev);  			continue;  		} @@ -207,15 +208,15 @@ int pcnet_initialize (bd_t * bis)  		dev->send = pcnet_send;  		dev->recv = pcnet_recv; -		eth_register (dev); +		eth_register(dev);  	} -	udelay (10 * 1000); +	udelay(10 * 1000);  	return dev_nr;  } -static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr) +static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr)  {  	int chip_version;  	char *chipname; @@ -225,17 +226,17 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  #endif  	/* Reset the PCnet controller */ -	pcnet_reset (dev); +	pcnet_reset(dev);  	/* Check if register access is working */ -	if (pcnet_read_csr (dev, 0) != 4 || !pcnet_check (dev)) { -		printf ("%s: CSR register access check failed\n", dev->name); +	if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) { +		printf("%s: CSR register access check failed\n", dev->name);  		return -1;  	}  	/* Identify the chip */  	chip_version = -		pcnet_read_csr (dev, 88) | (pcnet_read_csr (dev, 89) << 16); +		pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16);  	if ((chip_version & 0xfff) != 0x003)  		return -1;  	chip_version = (chip_version >> 12) & 0xffff; @@ -254,12 +255,12 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  		break;  #endif  	default: -		printf ("%s: PCnet version %#x not supported\n", -			dev->name, chip_version); +		printf("%s: PCnet version %#x not supported\n", +		       dev->name, chip_version);  		return -1;  	} -	PCNET_DEBUG1 ("AMD %s\n", chipname); +	PCNET_DEBUG1("AMD %s\n", chipname);  #ifdef PCNET_HAS_PROM  	/* @@ -270,7 +271,7 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  	for (i = 0; i < 3; i++) {  		unsigned int val; -		val = pcnet_read_csr (dev, i + 12) & 0x0ffff; +		val = pcnet_read_csr(dev, i + 12) & 0x0ffff;  		/* There may be endianness issues here. */  		dev->enetaddr[2 * i] = val & 0x0ff;  		dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; @@ -280,35 +281,40 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  	return 0;  } -static int pcnet_init (struct eth_device *dev, bd_t * bis) +static int pcnet_init(struct eth_device *dev, bd_t *bis)  {  	int i, val;  	u32 addr; -	PCNET_DEBUG1 ("%s: pcnet_init...\n", dev->name); +	PCNET_DEBUG1("%s: pcnet_init...\n", dev->name);  	/* Switch pcnet to 32bit mode */ -	pcnet_write_bcr (dev, 20, 2); - -#ifdef CONFIG_PN62 -	/* Setup LED registers */ -	val = pcnet_read_bcr (dev, 2) | 0x1000; -	pcnet_write_bcr (dev, 2, val);	/* enable LEDPE */ -	pcnet_write_bcr (dev, 4, 0x5080);	/* 100MBit */ -	pcnet_write_bcr (dev, 5, 0x40c0);	/* LNKSE */ -	pcnet_write_bcr (dev, 6, 0x4090);	/* TX Activity */ -	pcnet_write_bcr (dev, 7, 0x4084);	/* RX Activity */ -#endif +	pcnet_write_bcr(dev, 20, 2);  	/* Set/reset autoselect bit */ -	val = pcnet_read_bcr (dev, 2) & ~2; +	val = pcnet_read_bcr(dev, 2) & ~2;  	val |= 2; -	pcnet_write_bcr (dev, 2, val); +	pcnet_write_bcr(dev, 2, val);  	/* Enable auto negotiate, setup, disable fd */ -	val = pcnet_read_bcr (dev, 32) & ~0x98; +	val = pcnet_read_bcr(dev, 32) & ~0x98;  	val |= 0x20; -	pcnet_write_bcr (dev, 32, val); +	pcnet_write_bcr(dev, 32, val); + +	/* +	 * Enable NOUFLO on supported controllers, with the transmit +	 * start point set to the full packet. This will cause entire +	 * packets to be buffered by the ethernet controller before +	 * transmission, eliminating underflows which are common on +	 * slower devices. Controllers which do not support NOUFLO will +	 * simply be left with a larger transmit FIFO threshold. +	 */ +	val = pcnet_read_bcr(dev, 18); +	val |= 1 << 11; +	pcnet_write_bcr(dev, 18, val); +	val = pcnet_read_csr(dev, 80); +	val |= 0x3 << 10; +	pcnet_write_csr(dev, 80, val);  	/*  	 * We only maintain one structure because the drivers will never @@ -316,12 +322,12 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis)  	 * must be aligned on 16-byte boundaries.  	 */  	if (lp == NULL) { -		addr = (u32) malloc (sizeof (pcnet_priv_t) + 0x10); +		addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);  		addr = (addr + 0xf) & ~0xf; -		lp = (pcnet_priv_t *) addr; +		lp = (pcnet_priv_t *)addr;  	} -	lp->init_block.mode = cpu_to_le16 (0x0000); +	lp->init_block.mode = cpu_to_le16(0x0000);  	lp->init_block.filter[0] = 0x00000000;  	lp->init_block.filter[1] = 0x00000000; @@ -330,9 +336,9 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis)  	 */  	lp->cur_rx = 0;  	for (i = 0; i < RX_RING_SIZE; i++) { -		lp->rx_ring[i].base = PCI_TO_MEM_LE (dev, lp->rx_buf[i]); -		lp->rx_ring[i].buf_length = cpu_to_le16 (-PKT_BUF_SZ); -		lp->rx_ring[i].status = cpu_to_le16 (0x8000); +		lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]); +		lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); +		lp->rx_ring[i].status = cpu_to_le16(0x8000);  		PCNET_DEBUG1  			("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n", i,  			 lp->rx_ring[i].base, lp->rx_ring[i].buf_length, @@ -352,48 +358,49 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis)  	/*  	 * Setup Init Block.  	 */ -	PCNET_DEBUG1 ("Init block at 0x%p: MAC", &lp->init_block); +	PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->init_block);  	for (i = 0; i < 6; i++) {  		lp->init_block.phys_addr[i] = dev->enetaddr[i]; -		PCNET_DEBUG1 (" %02x", lp->init_block.phys_addr[i]); +		PCNET_DEBUG1(" %02x", lp->init_block.phys_addr[i]);  	} -	lp->init_block.tlen_rlen = cpu_to_le16 (TX_RING_LEN_BITS | -						RX_RING_LEN_BITS); -	lp->init_block.rx_ring = PCI_TO_MEM_LE (dev, lp->rx_ring); -	lp->init_block.tx_ring = PCI_TO_MEM_LE (dev, lp->tx_ring); +	lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | +					       RX_RING_LEN_BITS); +	lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring); +	lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring); +	flush_dcache_range((unsigned long)lp, (unsigned long)&lp->rx_buf); -	PCNET_DEBUG1 ("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", -		      lp->init_block.tlen_rlen, -		      lp->init_block.rx_ring, lp->init_block.tx_ring); +	PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", +		     lp->init_block.tlen_rlen, +		     lp->init_block.rx_ring, lp->init_block.tx_ring);  	/*  	 * Tell the controller where the Init Block is located.  	 */ -	addr = PCI_TO_MEM (dev, &lp->init_block); -	pcnet_write_csr (dev, 1, addr & 0xffff); -	pcnet_write_csr (dev, 2, (addr >> 16) & 0xffff); +	addr = PCI_TO_MEM(dev, &lp->init_block); +	pcnet_write_csr(dev, 1, addr & 0xffff); +	pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); -	pcnet_write_csr (dev, 4, 0x0915); -	pcnet_write_csr (dev, 0, 0x0001);	/* start */ +	pcnet_write_csr(dev, 4, 0x0915); +	pcnet_write_csr(dev, 0, 0x0001);	/* start */  	/* Wait for Init Done bit */  	for (i = 10000; i > 0; i--) { -		if (pcnet_read_csr (dev, 0) & 0x0100) +		if (pcnet_read_csr(dev, 0) & 0x0100)  			break; -		udelay (10); +		udelay(10);  	}  	if (i <= 0) { -		printf ("%s: TIMEOUT: controller init failed\n", dev->name); -		pcnet_reset (dev); +		printf("%s: TIMEOUT: controller init failed\n", dev->name); +		pcnet_reset(dev);  		return -1;  	}  	/*  	 * Finally start network controller operation.  	 */ -	pcnet_write_csr (dev, 0, 0x0002); +	pcnet_write_csr(dev, 0, 0x0002);  	return 0;  } @@ -403,20 +410,25 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len)  	int i, status;  	struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx]; -	PCNET_DEBUG2 ("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, -		      packet); +	PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, +		     packet); + +	flush_dcache_range((unsigned long)packet, +			   (unsigned long)packet + pkt_len);  	/* Wait for completion by testing the OWN bit */  	for (i = 1000; i > 0; i--) { -		status = le16_to_cpu (entry->status); +		invalidate_dcache_range((unsigned long)entry, +					(unsigned long)entry + sizeof(*entry)); +		status = le16_to_cpu(entry->status);  		if ((status & 0x8000) == 0)  			break; -		udelay (100); -		PCNET_DEBUG2 ("."); +		udelay(100); +		PCNET_DEBUG2(".");  	}  	if (i <= 0) { -		printf ("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", -			dev->name, lp->cur_tx, status); +		printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", +		       dev->name, lp->cur_tx, status);  		pkt_len = 0;  		goto failure;  	} @@ -426,19 +438,21 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len)  	 * set the status with the "ownership" bits last.  	 */  	status = 0x8300; -	entry->length = le16_to_cpu (-pkt_len); +	entry->length = cpu_to_le16(-pkt_len);  	entry->misc = 0x00000000; -	entry->base = PCI_TO_MEM_LE (dev, packet); -	entry->status = le16_to_cpu (status); +	entry->base = PCI_TO_MEM_LE(dev, packet); +	entry->status = cpu_to_le16(status); +	flush_dcache_range((unsigned long)entry, +			   (unsigned long)entry + sizeof(*entry));  	/* Trigger an immediate send poll. */ -	pcnet_write_csr (dev, 0, 0x0008); +	pcnet_write_csr(dev, 0, 0x0008);        failure:  	if (++lp->cur_tx >= TX_RING_SIZE)  		lp->cur_tx = 0; -	PCNET_DEBUG2 ("done\n"); +	PCNET_DEBUG2("done\n");  	return pkt_len;  } @@ -450,43 +464,49 @@ static int pcnet_recv (struct eth_device *dev)  	while (1) {  		entry = &lp->rx_ring[lp->cur_rx]; +		invalidate_dcache_range((unsigned long)entry, +					(unsigned long)entry + sizeof(*entry));  		/*  		 * If we own the next entry, it's a new packet. Send it up.  		 */ -		if (((status = le16_to_cpu (entry->status)) & 0x8000) != 0) { +		status = le16_to_cpu(entry->status); +		if ((status & 0x8000) != 0)  			break; -		}  		status >>= 8;  		if (status != 0x03) {	/* There was an error. */ - -			printf ("%s: Rx%d", dev->name, lp->cur_rx); -			PCNET_DEBUG1 (" (status=0x%x)", status); +			printf("%s: Rx%d", dev->name, lp->cur_rx); +			PCNET_DEBUG1(" (status=0x%x)", status);  			if (status & 0x20) -				printf (" Frame"); +				printf(" Frame");  			if (status & 0x10) -				printf (" Overflow"); +				printf(" Overflow");  			if (status & 0x08) -				printf (" CRC"); +				printf(" CRC");  			if (status & 0x04) -				printf (" Fifo"); -			printf (" Error\n"); -			entry->status &= le16_to_cpu (0x03ff); +				printf(" Fifo"); +			printf(" Error\n"); +			entry->status &= le16_to_cpu(0x03ff);  		} else { - -			pkt_len = -				(le32_to_cpu (entry->msg_length) & 0xfff) - 4; +			pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;  			if (pkt_len < 60) { -				printf ("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len); +				printf("%s: Rx%d: invalid packet length %d\n", +				       dev->name, lp->cur_rx, pkt_len);  			} else { -				NetReceive (lp->rx_buf[lp->cur_rx], pkt_len); -				PCNET_DEBUG2 ("Rx%d: %d bytes from 0x%p\n", -					      lp->cur_rx, pkt_len, -					      lp->rx_buf[lp->cur_rx]); +				invalidate_dcache_range( +					(unsigned long)lp->rx_buf[lp->cur_rx], +					(unsigned long)lp->rx_buf[lp->cur_rx] + +					pkt_len); +				NetReceive(lp->rx_buf[lp->cur_rx], pkt_len); +				PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", +					     lp->cur_rx, pkt_len, +					     lp->rx_buf[lp->cur_rx]);  			}  		} -		entry->status |= cpu_to_le16 (0x8000); +		entry->status |= cpu_to_le16(0x8000); +		flush_dcache_range((unsigned long)entry, +				   (unsigned long)entry + sizeof(*entry));  		if (++lp->cur_rx >= RX_RING_SIZE)  			lp->cur_rx = 0; @@ -494,22 +514,21 @@ static int pcnet_recv (struct eth_device *dev)  	return pkt_len;  } -static void pcnet_halt (struct eth_device *dev) +static void pcnet_halt(struct eth_device *dev)  {  	int i; -	PCNET_DEBUG1 ("%s: pcnet_halt...\n", dev->name); +	PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name);  	/* Reset the PCnet controller */ -	pcnet_reset (dev); +	pcnet_reset(dev);  	/* Wait for Stop bit */  	for (i = 1000; i > 0; i--) { -		if (pcnet_read_csr (dev, 0) & 0x4) +		if (pcnet_read_csr(dev, 0) & 0x4)  			break; -		udelay (10); -	} -	if (i <= 0) { -		printf ("%s: TIMEOUT: controller reset failed\n", dev->name); +		udelay(10);  	} +	if (i <= 0) +		printf("%s: TIMEOUT: controller reset failed\n", dev->name);  } diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c index 0f2dfd612..b20b4df98 100644 --- a/drivers/net/phy/atheros.c +++ b/drivers/net/phy/atheros.c @@ -40,7 +40,7 @@ static int ar8035_config(struct phy_device *phydev)  static struct phy_driver AR8021_driver =  {  	.name = "AR8021",  	.uid = 0x4dd040, -	.mask = 0xfffff0, +	.mask = 0x4fffff,  	.features = PHY_GBIT_FEATURES,  	.config = ar8021_config,  	.startup = genphy_startup, @@ -48,11 +48,11 @@ static struct phy_driver AR8021_driver =  {  };  static struct phy_driver AR8031_driver =  { -	.name = "AR8031", +	.name = "AR8031/AR8033",  	.uid = 0x4dd074, -	.mask = 0xfffff0, +	.mask = 0x4fffff,  	.features = PHY_GBIT_FEATURES, -	.config = genphy_config, +	.config = ar8021_config,  	.startup = genphy_startup,  	.shutdown = genphy_shutdown,  }; diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index a7450f832..5d7e3be52 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -100,6 +100,19 @@ int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)  	return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);  } + +static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr, +			      int regnum) +{ +	return ksz9021_phy_extended_read(phydev, regnum); +} + +static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr, +			       int devaddr, int regnum, u16 val) +{ +	return ksz9021_phy_extended_write(phydev, regnum, val); +} +  /* Micrel ksz9021 */  static int ksz9021_config(struct phy_device *phydev)  { @@ -131,6 +144,8 @@ static struct phy_driver ksz9021_driver = {  	.config = &ksz9021_config,  	.startup = &ksz90xx_startup,  	.shutdown = &genphy_shutdown, +	.writeext = &ksz9021_phy_extwrite, +	.readext = &ksz9021_phy_extread,  };  #endif @@ -171,14 +186,31 @@ int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,  	return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);  } +static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr, +			       int regnum) +{ +	return ksz9031_phy_extended_read(phydev, devaddr, regnum, +					 MII_KSZ9031_MOD_DATA_NO_POST_INC); +}; + +static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr, +				int devaddr, int regnum, u16 val) +{ +	return ksz9031_phy_extended_write(phydev, devaddr, regnum, +					 MII_KSZ9031_MOD_DATA_POST_INC_RW, val); +}; + +  static struct phy_driver ksz9031_driver = {  	.name = "Micrel ksz9031",  	.uid  = 0x221620, -	.mask = 0xfffffe, +	.mask = 0xfffff0,  	.features = PHY_GBIT_FEATURES,  	.config   = &genphy_config,  	.startup  = &ksz90xx_startup,  	.shutdown = &genphy_shutdown, +	.writeext = &ksz9031_phy_extwrite, +	.readext = &ksz9031_phy_extread,  };  int phy_micrel_init(void) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 62925bb28..c691fbbbc 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -275,13 +275,14 @@ int genphy_parse_link(struct phy_device *phydev)  	int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);  	/* We're using autonegotiation */ -	if (mii_reg & BMSR_ANEGCAPABLE) { +	if (phydev->supported & SUPPORTED_Autoneg) {  		u32 lpa = 0;  		int gblpa = 0;  		u32 estatus = 0;  		/* Check for gigabit capability */ -		if (mii_reg & BMSR_ERCAP) { +		if (phydev->supported & (SUPPORTED_1000baseT_Full | +					SUPPORTED_1000baseT_Half)) {  			/* We want a list of states supported by  			 * both PHYs in the link  			 */ diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index ddbbc35e2..a3ace6852 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -102,7 +102,7 @@ static int rtl8211x_startup(struct phy_device *phydev)  static struct phy_driver RTL8211B_driver = {  	.name = "RealTek RTL8211B",  	.uid = 0x1cc910, -	.mask = 0xfffff0, +	.mask = 0xffffff,  	.features = PHY_GBIT_FEATURES,  	.config = &rtl8211x_config,  	.startup = &rtl8211x_startup, @@ -113,7 +113,7 @@ static struct phy_driver RTL8211B_driver = {  static struct phy_driver RTL8211E_driver = {  	.name = "RealTek RTL8211E",  	.uid = 0x1cc915, -	.mask = 0xfffff0, +	.mask = 0xffffff,  	.features = PHY_GBIT_FEATURES,  	.config = &rtl8211x_config,  	.startup = &rtl8211x_startup, @@ -124,7 +124,7 @@ static struct phy_driver RTL8211E_driver = {  static struct phy_driver RTL8211DN_driver = {  	.name = "RealTek RTL8211DN",  	.uid = 0x1cc914, -	.mask = 0xfffff0, +	.mask = 0xffffff,  	.features = PHY_GBIT_FEATURES,  	.config = &rtl8211x_config,  	.startup = &rtl8211x_startup, diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 60ed92d20..bfd9815ab 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -12,6 +12,7 @@   */  #include <miiphy.h> +/* This code does not check the partner abilities. */  static int smsc_parse_status(struct phy_device *phydev)  {  	int mii_reg; @@ -64,7 +65,7 @@ static struct phy_driver lan8710_driver = {  	.mask = 0xffff0,  	.features = PHY_BASIC_FEATURES,  	.config = &genphy_config_aneg, -	.startup = &smsc_startup, +	.startup = &genphy_startup,  	.shutdown = &genphy_shutdown,  }; diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 5cf103e5a..c55597966 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -49,6 +49,15 @@  #define MIIM_VSC8574_18G_QSGMII		0x80e0  #define MIIM_VSC8574_18G_CMDSTAT	0x8000 +/* Vitesse VSC8514 control register */ +#define MIIM_VSC8514_GENERAL18		0x12 +#define MIIM_VSC8514_GENERAL19		0x13 +#define MIIM_VSC8514_GENERAL23		0x17 + +/* Vitesse VSC8514 gerenal purpose register 18 */ +#define MIIM_VSC8514_18G_QSGMII		0x80e0 +#define MIIM_VSC8514_18G_CMDSTAT	0x8000 +  /* CIS8201 */  static int vitesse_config(struct phy_device *phydev)  { @@ -148,7 +157,7 @@ static int vsc8601_config(struct phy_device *phydev)  static int vsc8574_config(struct phy_device *phydev)  {  	u32 val; -	/* configure regiser 19G for MAC */ +	/* configure register 19G for MAC */  	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,  		  PHY_EXT_PAGE_ACCESS_GENERAL); @@ -188,6 +197,53 @@ static int vsc8574_config(struct phy_device *phydev)  	return 0;  } +static int vsc8514_config(struct phy_device *phydev) +{ +	u32 val; +	int timeout = 1000000; + +	/* configure register to access 19G */ +	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, +		  PHY_EXT_PAGE_ACCESS_GENERAL); + +	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL19); +	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) { +		/* set bit 15:14 to '01' for QSGMII mode */ +		val = (val & 0x3fff) | (1 << 14); +		phy_write(phydev, MDIO_DEVAD_NONE, +			  MIIM_VSC8514_GENERAL19, val); +		/* Enable 4 ports MAC QSGMII */ +		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18, +			  MIIM_VSC8514_18G_QSGMII); +	} else { +		/*TODO Add SGMII functionality once spec sheet +		 * for VSC8514 defines complete functionality +		 */ +	} + +	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18); +	/* When bit 15 is cleared the command has completed */ +	while ((val & MIIM_VSC8514_18G_CMDSTAT) && timeout--) +		val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18); + +	if (0 == timeout) { +		printf("PHY 8514 config failed\n"); +		return -1; +	} + +	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0); + +	/* configure register to access 23 */ +	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23); +	/* set bits 10:8 to '000' */ +	val = (val & 0xf8ff); +	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23, val); + +	genphy_config_aneg(phydev); + +	return 0; +} +  static struct phy_driver VSC8211_driver = {  	.name	= "Vitesse VSC8211",  	.uid	= 0xfc4b0, @@ -238,6 +294,16 @@ static struct phy_driver VSC8574_driver = {  	.shutdown = &genphy_shutdown,  }; +static struct phy_driver VSC8514_driver = { +	.name = "Vitesse VSC8514", +	.uid = 0x70570, +	.mask = 0xffff0, +	.features = PHY_GBIT_FEATURES, +	.config = &vsc8514_config, +	.startup = &vitesse_startup, +	.shutdown = &genphy_shutdown, +}; +  static struct phy_driver VSC8601_driver = {  	.name = "Vitesse VSC8601",  	.uid = 0x70420, @@ -298,6 +364,7 @@ int phy_vitesse_init(void)  	phy_register(&VSC8211_driver);  	phy_register(&VSC8221_driver);  	phy_register(&VSC8574_driver); +	phy_register(&VSC8514_driver);  	phy_register(&VSC8662_driver);  	phy_register(&cis8201_driver);  	phy_register(&cis8204_driver); diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 4186699ff..208ce5ccc 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -188,7 +188,7 @@ static int rtl_transmit(struct eth_device *dev, void *packet, int length);  static int rtl_poll(struct eth_device *dev);  static void rtl_disable(struct eth_device *dev);  #ifdef CONFIG_MCAST_TFTP/*  This driver already accepts all b/mcast */ -static int rtl_bcast_addr (struct eth_device *dev, u8 bcast_mac, u8 set) +static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set)  {  	return (0);  } diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 13fa9c02f..d040ab171 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -246,6 +246,8 @@ static struct {  	{"RTL-8169sc/8110sc",	0x18, 0xff7e1880,},  	{"RTL-8168b/8111sb",	0x30, 0xff7e1880,},  	{"RTL-8168b/8111sb",	0x38, 0xff7e1880,}, +	{"RTL-8168d/8111d",	0x28, 0xff7e1880,}, +	{"RTL-8168evl/8111evl",	0x2e, 0xff7e1880,},  	{"RTL-8101e",		0x34, 0xff7e1880,},  	{"RTL-8100e",		0x32, 0xff7e1880,},  }; @@ -314,6 +316,7 @@ static const unsigned int rtl8169_rx_config =  static struct pci_device_id supported[] = {  	{PCI_VENDOR_ID_REALTEK, 0x8167}, +	{PCI_VENDOR_ID_REALTEK, 0x8168},  	{PCI_VENDOR_ID_REALTEK, 0x8169},  	{}  }; @@ -394,6 +397,50 @@ match:  	return 0;  } +/* + * Cache maintenance functions. These are simple wrappers around the more + * general purpose flush_cache() and invalidate_dcache_range() functions. + */ + +static void rtl_inval_rx_desc(struct RxDesc *desc) +{ +	unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); +	unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN); + +	invalidate_dcache_range(start, end); +} + +static void rtl_flush_rx_desc(struct RxDesc *desc) +{ +	flush_cache((unsigned long)desc, sizeof(*desc)); +} + +static void rtl_inval_tx_desc(struct TxDesc *desc) +{ +	unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); +	unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN); + +	invalidate_dcache_range(start, end); +} + +static void rtl_flush_tx_desc(struct TxDesc *desc) +{ +	flush_cache((unsigned long)desc, sizeof(*desc)); +} + +static void rtl_inval_buffer(void *buf, size_t size) +{ +	unsigned long start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); +	unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN); + +	invalidate_dcache_range(start, end); +} + +static void rtl_flush_buffer(void *buf, size_t size) +{ +	flush_cache((unsigned long)buf, size); +} +  /**************************************************************************  RECV - Receive a frame  ***************************************************************************/ @@ -411,14 +458,16 @@ static int rtl_recv(struct eth_device *dev)  	ioaddr = dev->iobase;  	cur_rx = tpc->cur_rx; -	flush_cache((unsigned long)&tpc->RxDescArray[cur_rx], -			sizeof(struct RxDesc)); + +	rtl_inval_rx_desc(&tpc->RxDescArray[cur_rx]); +  	if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) {  		if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) {  			unsigned char rxdata[RX_BUF_LEN];  			length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx].  						status) & 0x00001FFF) - 4; +			rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length);  			memcpy(rxdata, tpc->RxBufferRing[cur_rx], length);  			NetReceive(rxdata, length); @@ -430,8 +479,7 @@ static int rtl_recv(struct eth_device *dev)  					cpu_to_le32(OWNbit + RX_BUF_SIZE);  			tpc->RxDescArray[cur_rx].buf_addr =  				cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx])); -			flush_cache((unsigned long)tpc->RxBufferRing[cur_rx], -					RX_BUF_SIZE); +			rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);  		} else {  			puts("Error Rx");  		} @@ -473,7 +521,7 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)  	/* point to the current txb incase multiple tx_rings are used */  	ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];  	memcpy(ptxb, (char *)packet, (int)length); -	flush_cache((unsigned long)ptxb, length); +	rtl_flush_buffer(ptxb, length);  	while (len < ETH_ZLEN)  		ptxb[len++] = '\0'; @@ -489,20 +537,20 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)  			cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) |  				    ((len > ETH_ZLEN) ? len : ETH_ZLEN));  	} +	rtl_flush_tx_desc(&tpc->TxDescArray[entry]);  	RTL_W8(TxPoll, 0x40);	/* set polling bit */  	tpc->cur_tx++;  	to = currticks() + TX_TIMEOUT;  	do { -		flush_cache((unsigned long)&tpc->TxDescArray[entry], -				sizeof(struct TxDesc)); +		rtl_inval_tx_desc(&tpc->TxDescArray[entry]);  	} while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit)  				&& (currticks() < to));	/* wait */  	if (currticks() >= to) {  #ifdef DEBUG_RTL8169_TX -		puts ("tx timeout/error\n"); -		printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); +		puts("tx timeout/error\n"); +		printf("%s elapsed time : %lu\n", __func__, currticks()-stime);  #endif  		ret = 0;  	} else { @@ -604,7 +652,7 @@ static void rtl8169_hw_start(struct eth_device *dev)  	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);  #ifdef DEBUG_RTL8169 -	printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); +	printf("%s elapsed time : %lu\n", __func__, currticks()-stime);  #endif  } @@ -638,11 +686,11 @@ static void rtl8169_init_ring(struct eth_device *dev)  		tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];  		tpc->RxDescArray[i].buf_addr =  			cpu_to_le32(bus_to_phys(tpc->RxBufferRing[i])); -		flush_cache((unsigned long)tpc->RxBufferRing[i], RX_BUF_SIZE); +		rtl_flush_rx_desc(&tpc->RxDescArray[i]);  	}  #ifdef DEBUG_RTL8169 -	printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); +	printf("%s elapsed time : %lu\n", __func__, currticks()-stime);  #endif  } @@ -683,7 +731,7 @@ static int rtl_reset(struct eth_device *dev, bd_t *bis)  	txb[5] = dev->enetaddr[5];  #ifdef DEBUG_RTL8169 -	printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); +	printf("%s elapsed time : %lu\n", __func__, currticks()-stime);  #endif  	return 0;  } @@ -869,11 +917,25 @@ int rtl8169_initialize(bd_t *bis)  	int idx=0;  	while(1){ +		unsigned int region; +		u16 device; +  		/* Find RTL8169 */  		if ((devno = pci_find_devices(supported, idx++)) < 0)  			break; -		pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); +		pci_read_config_word(devno, PCI_DEVICE_ID, &device); +		switch (device) { +		case 0x8168: +			region = 2; +			break; + +		default: +			region = 1; +			break; +		} + +		pci_read_config_dword(devno, PCI_BASE_ADDRESS_0 + (region * 4), &iobase);  		iobase &= ~0xf;  		debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index d5a83e0bf..5e132f2b5 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -4,6 +4,7 @@   * Copyright (C) 2008, 2011 Renesas Solutions Corp.   * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu   * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com> + * Copyright (C) 2013  Renesas Electronics Corporation   *   * SPDX-License-Identifier:	GPL-2.0+   */ @@ -25,13 +26,31 @@  #ifndef CONFIG_SH_ETHER_PHY_ADDR  # error "Please define CONFIG_SH_ETHER_PHY_ADDR"  #endif -#ifdef CONFIG_SH_ETHER_CACHE_WRITEBACK -#define flush_cache_wback(addr, len)	\ -			dcache_wback_range((u32)addr, (u32)(addr + len - 1)) + +#if defined(CONFIG_SH_ETHER_CACHE_WRITEBACK) && !defined(CONFIG_SYS_DCACHE_OFF) +#define flush_cache_wback(addr, len)    \ +		flush_dcache_range((u32)addr, (u32)(addr + len - 1))  #else  #define flush_cache_wback(...)  #endif +#if defined(CONFIG_SH_ETHER_CACHE_INVALIDATE) && defined(CONFIG_ARM) +#define invalidate_cache(addr, len)		\ +	{	\ +		u32 line_size = CONFIG_SH_ETHER_ALIGNE_SIZE;	\ +		u32 start, end;	\ +		\ +		start = (u32)addr;	\ +		end = start + len;	\ +		start &= ~(line_size - 1);	\ +		end = ((end + line_size - 1) & ~(line_size - 1));	\ +		\ +		invalidate_dcache_range(start, end);	\ +	} +#else +#define invalidate_cache(...) +#endif +  #define TIMEOUT_CNT 1000  int sh_eth_send(struct eth_device *dev, void *packet, int len) @@ -69,8 +88,11 @@ int sh_eth_send(struct eth_device *dev, void *packet, int len)  	/* Wait until packet is transmitted */  	timeout = TIMEOUT_CNT; -	while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--) +	do { +		invalidate_cache(port_info->tx_desc_cur, +				 sizeof(struct tx_desc_s));  		udelay(100); +	} while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--);  	if (timeout < 0) {  		printf(SHETHER_NAME ": transmit timeout\n"); @@ -94,12 +116,14 @@ int sh_eth_recv(struct eth_device *dev)  	uchar *packet;  	/* Check if the rx descriptor is ready */ +	invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s));  	if (!(port_info->rx_desc_cur->rd0 & RD_RACT)) {  		/* Check for errors */  		if (!(port_info->rx_desc_cur->rd0 & RD_RFE)) {  			len = port_info->rx_desc_cur->rd1 & 0xffff;  			packet = (uchar *)  				ADDR_TO_P2(port_info->rx_desc_cur->rd2); +			invalidate_cache(packet, len);  			NetReceive(packet, len);  		} @@ -108,7 +132,6 @@ int sh_eth_recv(struct eth_device *dev)  			port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE;  		else  			port_info->rx_desc_cur->rd0 = RD_RACT; -  		/* Point to the next descriptor */  		port_info->rx_desc_cur++;  		if (port_info->rx_desc_cur >= @@ -237,15 +260,17 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)  	 * Allocate rx data buffers. They must be 32 bytes aligned  and in  	 * P2 area  	 */ -	port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + 31); +	port_info->rx_buf_malloc = malloc( +		NUM_RX_DESC * MAX_BUF_SIZE + RX_BUF_ALIGNE_SIZE - 1);  	if (!port_info->rx_buf_malloc) {  		printf(SHETHER_NAME ": malloc failed\n");  		ret = -ENOMEM;  		goto err_buf_malloc;  	} -	tmp_addr = (u32)(((int)port_info->rx_buf_malloc + (32 - 1)) & -			  ~(32 - 1)); +	tmp_addr = (u32)(((int)port_info->rx_buf_malloc +			  + (RX_BUF_ALIGNE_SIZE - 1)) & +			  ~(RX_BUF_ALIGNE_SIZE - 1));  	port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr);  	/* Initialize all descriptors */ @@ -351,8 +376,9 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)  	struct phy_device *phy;  	/* Configure e-dmac registers */ -	sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | EDMR_EL, -		     EDMR); +	sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | +			(EMDR_DESC | EDMR_EL), EDMR); +  	sh_eth_write(eth, 0, EESIPR);  	sh_eth_write(eth, 0, TRSCER);  	sh_eth_write(eth, 0, TFTR); @@ -384,6 +410,8 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)  #if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740)  	sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); +#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) +	sh_eth_write(eth, sh_eth_read(eth, RMIIMR) | 0x1, RMIIMR);  #endif  	/* Configure phy */  	ret = sh_eth_phy_config(eth); @@ -407,7 +435,8 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)  		sh_eth_write(eth, GECMR_100B, GECMR);  #elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)  		sh_eth_write(eth, 1, RTRATE); -#elif defined(CONFIG_CPU_SH7724) +#elif defined(CONFIG_CPU_SH7724) || defined(CONFIG_R8A7790) || \ +		defined(CONFIG_R8A7791)  		val = ECMR_RTM;  #endif  	} else if (phy->speed == 10) { diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 9ad800e42..8aa71098c 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -31,6 +31,11 @@  #define ADDR_TO_P2(addr)	(addr)  #endif /* defined(CONFIG_SH) */ +/* base padding size is 16 */ +#ifndef CONFIG_SH_ETHER_ALIGNE_SIZE +#define CONFIG_SH_ETHER_ALIGNE_SIZE 16 +#endif +  /* Number of supported ports */  #define MAX_PORT_NUM	2 @@ -45,15 +50,16 @@  /* The size of the tx descriptor is determined by how much padding is used.     4, 20, or 52 bytes of padding can be used */ -#define TX_DESC_PADDING		4 -#define TX_DESC_SIZE		(12 + TX_DESC_PADDING) +#define TX_DESC_PADDING	(CONFIG_SH_ETHER_ALIGNE_SIZE - 12) +/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */ +#define TX_DESC_SIZE	(12 + TX_DESC_PADDING)  /* Tx descriptor. We always use 3 bytes of padding */  struct tx_desc_s {  	volatile u32 td0;  	u32 td1;  	u32 td2;		/* Buffer start */ -	u32 padding; +	u8 padding[TX_DESC_PADDING];	/* aligned cache line size */  };  /* There is no limitation in the number of rx descriptors */ @@ -61,15 +67,18 @@ struct tx_desc_s {  /* The size of the rx descriptor is determined by how much padding is used.     4, 20, or 52 bytes of padding can be used */ -#define RX_DESC_PADDING		4 +#define RX_DESC_PADDING	(CONFIG_SH_ETHER_ALIGNE_SIZE - 12) +/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */  #define RX_DESC_SIZE		(12 + RX_DESC_PADDING) +/* aligned cache line size */ +#define RX_BUF_ALIGNE_SIZE	(CONFIG_SH_ETHER_ALIGNE_SIZE > 32 ? 64 : 32)  /* Rx descriptor. We always use 4 bytes of padding */  struct rx_desc_s {  	volatile u32 rd0;  	volatile u32 rd1;  	u32 rd2;		/* Buffer start */ -	u32 padding; +	u8 padding[TX_DESC_PADDING];	/* aligned cache line size */  };  struct sh_eth_info { @@ -157,6 +166,7 @@ enum {  	TLFRCR,  	CERCR,  	CEECR, +	RMIIMR, /* R8A7790 */  	MAFCR,  	RTRATE,  	CSMR, @@ -263,6 +273,7 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {  	[RMCR]	= 0x0058,  	[TFUCR]	= 0x0064,  	[RFOCR]	= 0x0068, +	[RMIIMR] = 0x006C,  	[FCFTR]	= 0x0070,  	[RPADIR]	= 0x0078,  	[TRIMD]	= 0x007c, @@ -290,6 +301,9 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {  #elif defined(CONFIG_R8A7740)  #define SH_ETH_TYPE_GETHER  #define BASE_IO_ADDR	0xE9A00000 +#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) +#define SH_ETH_TYPE_ETHER +#define BASE_IO_ADDR	0xEE700200  #endif  /* @@ -320,6 +334,14 @@ enum DMAC_M_BIT {  #endif  }; +#if CONFIG_SH_ETHER_ALIGNE_SIZE == 64 +# define EMDR_DESC EDMR_DL1 +#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 32 +# define EMDR_DESC EDMR_DL0 +#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 16 /* Default */ +# define EMDR_DESC 0 +#endif +  /* RFLR */  #define RFLR_RFL_MIN	0x05EE	/* Recv Frame length 1518 byte */ @@ -485,6 +507,8 @@ enum FELIC_MODE_BIT {  	ECMR_PRM = 0x00000001,  #ifdef CONFIG_CPU_SH7724  	ECMR_RTM = 0x00000010, +#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) +	ECMR_RTM = 0x00000004,  #endif  }; diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index f5e314b9e..e9138f033 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -5,7 +5,7 @@   * terms of the GNU Public License, Version 2, incorporated   * herein by reference.   * - * Copyright 2004-2011 Freescale Semiconductor, Inc. + * Copyright 2004-2011, 2013 Freescale Semiconductor, Inc.   * (C) Copyright 2003, Motorola, Inc.   * author Andy Fleming   * @@ -25,21 +25,13 @@ DECLARE_GLOBAL_DATA_PTR;  #define TX_BUF_CNT		2 -static uint rxIdx;		/* index of the current RX buffer */ -static uint txIdx;		/* index of the current TX buffer */ - -typedef volatile struct rtxbd { -	txbd8_t txbd[TX_BUF_CNT]; -	rxbd8_t rxbd[PKTBUFSRX]; -} RTXBD; - -#define MAXCONTROLLERS	(8) - -static struct tsec_private *privlist[MAXCONTROLLERS]; -static int num_tsecs = 0; +static uint rx_idx;		/* index of the current RX buffer */ +static uint tx_idx;		/* index of the current TX buffer */  #ifdef __GNUC__ -static RTXBD rtx __attribute__ ((aligned(8))); +static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8); +static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8); +  #else  #error "rtx must be 64-bit aligned"  #endif @@ -57,7 +49,7 @@ static struct tsec_info_struct tsec_info[] = {  #endif  #ifdef CONFIG_MPC85XX_FEC  	{ -		.regs = (tsec_t *)(TSEC_BASE_ADDR + 0x2000), +		.regs = TSEC_GET_REGS(2, 0x2000),  		.devname = CONFIG_MPC85XX_FEC_NAME,  		.phyaddr = FEC_PHY_ADDR,  		.flags = FEC_FLAGS, @@ -113,32 +105,31 @@ static void tsec_configure_serdes(struct tsec_private *priv)   * result.   * 2) Use the 8 most significant bits as a hash into a 256-entry   * table.  The table is controlled through 8 32-bit registers: - * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is - * gaddr7.  This means that the 3 most significant bits in the + * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is entry + * 255.  This means that the 3 most significant bits in the   * hash index which gaddr register to use, and the 5 other bits   * indicate which bit (assuming an IBM numbering scheme, which - * for PowerPC (tm) is usually the case) in the tregister holds + * for PowerPC (tm) is usually the case) in the register holds   * the entry. */  static int -tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) +tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set)  { -	struct tsec_private *priv = privlist[1]; -	volatile tsec_t *regs = priv->regs; -	volatile u32  *reg_array, value; -	u8 result, whichbit, whichreg; +	struct tsec_private *priv = (struct tsec_private *)dev->priv; +	struct tsec __iomem *regs = priv->regs; +	u32 result, value; +	u8 whichbit, whichreg; -	result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff); -	whichbit = result & 0x1f;	/* the 5 LSB = which bit to set */ -	whichreg = result >> 5;		/* the 3 MSB = which reg to set it in */ -	value = (1 << (31-whichbit)); +	result = ether_crc(MAC_ADDR_LEN, mcast_mac); +	whichbit = (result >> 24) & 0x1f; /* the 5 LSB = which bit to set */ +	whichreg = result >> 29; /* the 3 MSB = which reg to set it in */ -	reg_array = &(regs->hash.gaddr0); +	value = 1 << (31-whichbit); + +	if (set) +		setbits_be32(®s->hash.gaddr0 + whichreg, value); +	else +		clrbits_be32(®s->hash.gaddr0 + whichreg, value); -	if (set) { -		reg_array[whichreg] |= value; -	} else { -		reg_array[whichreg] &= ~value; -	}  	return 0;  }  #endif /* Multicast TFTP ? */ @@ -147,7 +138,7 @@ tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set)   * those we don't care about (unless zero is bad, in which case,   * choose a more appropriate value)   */ -static void init_registers(tsec_t *regs) +static void init_registers(struct tsec __iomem *regs)  {  	/* Clear IEVENT */  	out_be32(®s->ievent, IEVENT_INIT_CLEAR); @@ -175,7 +166,7 @@ static void init_registers(tsec_t *regs)  	out_be32(®s->rctrl, 0x00000000);  	/* Init RMON mib registers */ -	memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t)); +	memset((void *)®s->rmon, 0, sizeof(regs->rmon));  	out_be32(®s->rmon.cam1, 0xffffffff);  	out_be32(®s->rmon.cam2, 0xffffffff); @@ -194,7 +185,7 @@ static void init_registers(tsec_t *regs)   */  static void adjust_link(struct tsec_private *priv, struct phy_device *phydev)  { -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs;  	u32 ecntrl, maccfg2;  	if (!phydev->link) { @@ -248,7 +239,7 @@ static void adjust_link(struct tsec_private *priv, struct phy_device *phydev)  void redundant_init(struct eth_device *dev)  {  	struct tsec_private *priv = dev->priv; -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs;  	uint t, count = 0;  	int fail = 1;  	static const u8 pkt[] = { @@ -281,23 +272,26 @@ void redundant_init(struct eth_device *dev)  	clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);  	do { +		uint16_t status;  		tsec_send(dev, (void *)pkt, sizeof(pkt));  		/* Wait for buffer to be received */ -		for (t = 0; rtx.rxbd[rxIdx].status & RXBD_EMPTY; t++) { +		for (t = 0; in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY; t++) {  			if (t >= 10 * TOUT_LOOP) {  				printf("%s: tsec: rx error\n", dev->name);  				break;  			}  		} -		if (!memcmp(pkt, (void *)NetRxPackets[rxIdx], sizeof(pkt))) +		if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt)))  			fail = 0; -		rtx.rxbd[rxIdx].length = 0; -		rtx.rxbd[rxIdx].status = -		    RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); -		rxIdx = (rxIdx + 1) % PKTBUFSRX; +		out_be16(&rxbd[rx_idx].length, 0); +		status = RXBD_EMPTY; +		if ((rx_idx + 1) == PKTBUFSRX) +			status |= RXBD_WRAP; +		out_be16(&rxbd[rx_idx].status, status); +		rx_idx = (rx_idx + 1) % PKTBUFSRX;  		if (in_be32(®s->ievent) & IEVENT_BSY) {  			out_be32(®s->ievent, IEVENT_BSY); @@ -325,36 +319,39 @@ void redundant_init(struct eth_device *dev)   */  static void startup_tsec(struct eth_device *dev)  { -	int i;  	struct tsec_private *priv = (struct tsec_private *)dev->priv; -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs; +	uint16_t status; +	int i;  	/* reset the indices to zero */ -	rxIdx = 0; -	txIdx = 0; +	rx_idx = 0; +	tx_idx = 0;  #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129  	uint svr;  #endif  	/* Point to the buffer descriptors */ -	out_be32(®s->tbase, (unsigned int)(&rtx.txbd[txIdx])); -	out_be32(®s->rbase, (unsigned int)(&rtx.rxbd[rxIdx])); +	out_be32(®s->tbase, (u32)&txbd[0]); +	out_be32(®s->rbase, (u32)&rxbd[0]);  	/* Initialize the Rx Buffer descriptors */  	for (i = 0; i < PKTBUFSRX; i++) { -		rtx.rxbd[i].status = RXBD_EMPTY; -		rtx.rxbd[i].length = 0; -		rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i]; +		out_be16(&rxbd[i].status, RXBD_EMPTY); +		out_be16(&rxbd[i].length, 0); +		out_be32(&rxbd[i].bufptr, (u32)NetRxPackets[i]);  	} -	rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; +	status = in_be16(&rxbd[PKTBUFSRX - 1].status); +	out_be16(&rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP);  	/* Initialize the TX Buffer Descriptors */  	for (i = 0; i < TX_BUF_CNT; i++) { -		rtx.txbd[i].status = 0; -		rtx.txbd[i].length = 0; -		rtx.txbd[i].bufPtr = 0; +		out_be16(&txbd[i].status, 0); +		out_be16(&txbd[i].length, 0); +		out_be32(&txbd[i].bufptr, 0);  	} -	rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; +	status = in_be16(&txbd[TX_BUF_CNT - 1].status); +	out_be16(&txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP);  #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129  	svr = get_svr(); @@ -378,66 +375,67 @@ static void startup_tsec(struct eth_device *dev)   */  static int tsec_send(struct eth_device *dev, void *packet, int length)  { -	int i; -	int result = 0;  	struct tsec_private *priv = (struct tsec_private *)dev->priv; -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs; +	uint16_t status; +	int result = 0; +	int i;  	/* Find an empty buffer descriptor */ -	for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { +	for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) {  		if (i >= TOUT_LOOP) {  			debug("%s: tsec: tx buffers full\n", dev->name);  			return result;  		}  	} -	rtx.txbd[txIdx].bufPtr = (uint) packet; -	rtx.txbd[txIdx].length = length; -	rtx.txbd[txIdx].status |= -	    (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); +	out_be32(&txbd[tx_idx].bufptr, (u32)packet); +	out_be16(&txbd[tx_idx].length, length); +	status = in_be16(&txbd[tx_idx].status); +	out_be16(&txbd[tx_idx].status, status | +		(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT));  	/* Tell the DMA to go */  	out_be32(®s->tstat, TSTAT_CLEAR_THALT);  	/* Wait for buffer to be transmitted */ -	for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { +	for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) {  		if (i >= TOUT_LOOP) {  			debug("%s: tsec: tx error\n", dev->name);  			return result;  		}  	} -	txIdx = (txIdx + 1) % TX_BUF_CNT; -	result = rtx.txbd[txIdx].status & TXBD_STATS; +	tx_idx = (tx_idx + 1) % TX_BUF_CNT; +	result = in_be16(&txbd[tx_idx].status) & TXBD_STATS;  	return result;  }  static int tsec_recv(struct eth_device *dev)  { -	int length;  	struct tsec_private *priv = (struct tsec_private *)dev->priv; -	tsec_t *regs = priv->regs; - -	while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) { +	struct tsec __iomem *regs = priv->regs; -		length = rtx.rxbd[rxIdx].length; +	while (!(in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY)) { +		int length = in_be16(&rxbd[rx_idx].length); +		uint16_t status = in_be16(&rxbd[rx_idx].status);  		/* Send the packet up if there were no errors */ -		if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) { -			NetReceive(NetRxPackets[rxIdx], length - 4); -		} else { -			printf("Got error %x\n", -			       (rtx.rxbd[rxIdx].status & RXBD_STATS)); -		} +		if (!(status & RXBD_STATS)) +			NetReceive(NetRxPackets[rx_idx], length - 4); +		else +			printf("Got error %x\n", (status & RXBD_STATS)); -		rtx.rxbd[rxIdx].length = 0; +		out_be16(&rxbd[rx_idx].length, 0); +		status = RXBD_EMPTY;  		/* Set the wrap bit if this is the last element in the list */ -		rtx.rxbd[rxIdx].status = -		    RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); +		if ((rx_idx + 1) == PKTBUFSRX) +			status |= RXBD_WRAP; +		out_be16(&rxbd[rx_idx].status, status); -		rxIdx = (rxIdx + 1) % PKTBUFSRX; +		rx_idx = (rx_idx + 1) % PKTBUFSRX;  	}  	if (in_be32(®s->ievent) & IEVENT_BSY) { @@ -453,7 +451,7 @@ static int tsec_recv(struct eth_device *dev)  static void tsec_halt(struct eth_device *dev)  {  	struct tsec_private *priv = (struct tsec_private *)dev->priv; -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs;  	clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);  	setbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); @@ -475,11 +473,9 @@ static void tsec_halt(struct eth_device *dev)   */  static int tsec_init(struct eth_device *dev, bd_t * bd)  { -	uint tempval; -	char tmpbuf[MAC_ADDR_LEN]; -	int i;  	struct tsec_private *priv = (struct tsec_private *)dev->priv; -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs; +	u32 tempval;  	int ret;  	/* Make sure the controller is stopped */ @@ -492,16 +488,16 @@ static int tsec_init(struct eth_device *dev, bd_t * bd)  	out_be32(®s->ecntrl, ECNTRL_INIT_SETTINGS);  	/* Copy the station address into the address registers. -	 * Backwards, because little endian MACS are dumb */ -	for (i = 0; i < MAC_ADDR_LEN; i++) -		tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i]; - -	tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) | -		  tmpbuf[3]; +	 * For a station address of 0x12345678ABCD in transmission +	 * order (BE), MACnADDR1 is set to 0xCDAB7856 and +	 * MACnADDR2 is set to 0x34120000. +	 */ +	tempval = (dev->enetaddr[5] << 24) | (dev->enetaddr[4] << 16) | +		  (dev->enetaddr[3] << 8)  |  dev->enetaddr[2];  	out_be32(®s->macstnaddr1, tempval); -	tempval = *((uint *) (tmpbuf + 4)); +	tempval = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16);  	out_be32(®s->macstnaddr2, tempval); @@ -527,7 +523,7 @@ static int tsec_init(struct eth_device *dev, bd_t * bd)  static phy_interface_t tsec_get_interface(struct tsec_private *priv)  { -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs;  	u32 ecntrl;  	ecntrl = in_be32(®s->ecntrl); @@ -576,7 +572,7 @@ static int init_phy(struct eth_device *dev)  {  	struct tsec_private *priv = (struct tsec_private *)dev->priv;  	struct phy_device *phydev; -	tsec_t *regs = priv->regs; +	struct tsec __iomem *regs = priv->regs;  	u32 supported = (SUPPORTED_10baseT_Half |  			SUPPORTED_10baseT_Full |  			SUPPORTED_100baseT_Half | @@ -626,7 +622,6 @@ static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)  	if (NULL == priv)  		return 0; -	privlist[num_tsecs++] = priv;  	priv->regs = tsec_info->regs;  	priv->phyregs_sgmii = tsec_info->miiregs_sgmii; @@ -684,7 +679,7 @@ int tsec_standard_init(bd_t *bis)  {  	struct fsl_pq_mdio_info info; -	info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; +	info.regs = TSEC_GET_MDIO_REGS_BASE(1);  	info.name = DEFAULT_MII_NAME;  	fsl_pq_mdio_init(bis, &info); diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 236a75311..6a017a810 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -43,11 +43,6 @@  #define ZYNQ_GEM_TXBUF_WRAP_MASK	0x40000000  #define ZYNQ_GEM_TXBUF_LAST_MASK	0x00008000 /* Last buffer */ -#define ZYNQ_GEM_TXSR_HRESPNOK_MASK	0x00000100 /* Transmit hresp not OK */ -#define ZYNQ_GEM_TXSR_URUN_MASK		0x00000040 /* Transmit underrun */ -/* Transmit buffs exhausted mid frame */ -#define ZYNQ_GEM_TXSR_BUFEXH_MASK	0x00000010 -  #define ZYNQ_GEM_NWCTRL_TXEN_MASK	0x00000008 /* Enable transmit */  #define ZYNQ_GEM_NWCTRL_RXEN_MASK	0x00000004 /* Enable receive */  #define ZYNQ_GEM_NWCTRL_MDEN_MASK	0x00000010 /* Enable MDIO port */ @@ -90,6 +85,11 @@   */  #define PHY_DETECT_MASK 0x1808 +/* TX BD status masks */ +#define ZYNQ_GEM_TXBUF_FRMLEN_MASK	0x000007ff +#define ZYNQ_GEM_TXBUF_EXHAUSTED	0x08000000 +#define ZYNQ_GEM_TXBUF_UNDERRUN		0x10000000 +  /* Device registers */  struct zynq_gem_regs {  	u32 nwctrl; /* Network Control reg */ @@ -123,12 +123,18 @@ struct emac_bd {  };  #define RX_BUF 3 +/* Page table entries are set to 1MB, or multiples of 1MB + * (not < 1MB). driver uses less bd's so use 1MB bdspace. + */ +#define BD_SPACE	0x100000 +/* BD separation space */ +#define BD_SEPRN_SPACE	64  /* Initialized, rxbd_current, rx_first_buf must be 0 after init */  struct zynq_gem_priv { -	struct emac_bd tx_bd; -	struct emac_bd rx_bd[RX_BUF]; -	char rxbuffers[RX_BUF * PKTSIZE_ALIGN]; +	struct emac_bd *tx_bd; +	struct emac_bd *rx_bd; +	char *rxbuffers;  	u32 rxbd_current;  	u32 rx_first_buf;  	int phyaddr; @@ -299,20 +305,18 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)  			readl(®s->stat[i]);  		/* Setup RxBD space */ -		memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); -		/* Create the RxBD ring */ -		memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); +		memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));  		for (i = 0; i < RX_BUF; i++) {  			priv->rx_bd[i].status = 0xF0000000;  			priv->rx_bd[i].addr = -					(u32)((char *)&(priv->rxbuffers) + +					((u32)(priv->rxbuffers) +  							(i * PKTSIZE_ALIGN));  		}  		/* WRAP bit to last BD */  		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;  		/* Write RxBDs to IP */ -		writel((u32)&(priv->rx_bd), ®s->rxqbase); +		writel((u32)priv->rx_bd, ®s->rxqbase);  		/* Setup for DMA Configuration register */  		writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); @@ -368,32 +372,35 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)  static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)  { -	u32 status; +	u32 addr, size;  	struct zynq_gem_priv *priv = dev->priv;  	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; -	const u32 mask = ZYNQ_GEM_TXSR_HRESPNOK_MASK | \ -			ZYNQ_GEM_TXSR_URUN_MASK | ZYNQ_GEM_TXSR_BUFEXH_MASK;  	/* setup BD */ -	writel((u32)&(priv->tx_bd), ®s->txqbase); +	writel((u32)priv->tx_bd, ®s->txqbase);  	/* Setup Tx BD */ -	memset((void *)&(priv->tx_bd), 0, sizeof(struct emac_bd)); +	memset(priv->tx_bd, 0, sizeof(struct emac_bd)); + +	priv->tx_bd->addr = (u32)ptr; +	priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) | +				ZYNQ_GEM_TXBUF_LAST_MASK; -	priv->tx_bd.addr = (u32)ptr; -	priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK; +	addr = (u32) ptr; +	addr &= ~(ARCH_DMA_MINALIGN - 1); +	size = roundup(len, ARCH_DMA_MINALIGN); +	flush_dcache_range(addr, addr + size); +	barrier();  	/* Start transmit */  	setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); -	/* Read the stat register to know if the packet has been transmitted */ -	status = readl(®s->txsr); -	if (status & mask) -		printf("Something has gone wrong here!? Status is 0x%x.\n", -		       status); +	/* Read TX BD status */ +	if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_UNDERRUN) +		printf("TX underrun\n"); +	if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED) +		printf("TX buffers exhausted in mid frame\n"); -	/* Clear Tx status register before leaving . */ -	writel(status, ®s->txsr);  	return 0;  } @@ -416,8 +423,12 @@ static int zynq_gem_recv(struct eth_device *dev)  	frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK;  	if (frame_len) { -		NetReceive((u8 *) (current_bd->addr & -					ZYNQ_GEM_RXBUF_ADD_MASK), frame_len); +		u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK; +		addr &= ~(ARCH_DMA_MINALIGN - 1); +		u32 size = roundup(frame_len, ARCH_DMA_MINALIGN); +		invalidate_dcache_range(addr, addr + size); + +		NetReceive((u8 *)addr, frame_len);  		if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK)  			priv->rx_first_buf = priv->rxbd_current; @@ -471,6 +482,7 @@ int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio)  {  	struct eth_device *dev;  	struct zynq_gem_priv *priv; +	void *bd_space;  	dev = calloc(1, sizeof(*dev));  	if (dev == NULL) @@ -483,6 +495,18 @@ int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio)  	}  	priv = dev->priv; +	/* Align rxbuffers to ARCH_DMA_MINALIGN */ +	priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN); +	memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN); + +	/* Align bd_space to 1MB */ +	bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE); +	mmu_set_region_dcache_behaviour((u32)bd_space, BD_SPACE, DCACHE_OFF); + +	/* Initialize the bd spaces for tx and rx bd's */ +	priv->tx_bd = (struct emac_bd *)bd_space; +	priv->rx_bd = (struct emac_bd *)((u32)bd_space + BD_SEPRN_SPACE); +  	priv->phyaddr = phy_addr;  	priv->emio = emio; |