Exemple #1
0
/*
 * Write a MII PHY register.
 *
 * Returns:
 *  0 on success
 */
static int uec_miiphy_write(const char *devname, unsigned char addr,
			     unsigned char reg, unsigned short value)
{
	int devindex = 0;

	if (devname == NULL) {
		debug("%s: NULL pointer given\n", __FUNCTION__);
	} else {
		devindex = uec_miiphy_find_dev_by_name(devname);
		if (devindex >= 0) {
			uec_write_phy_reg(devlist[devindex], addr, reg, value);
		}
	}
	return 0;
}
Exemple #2
0
/*
 * Write a MII PHY register.
 *
 * Returns:
 *  0 on success
 */
static int uec_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
			    u16 value)
{
	int devindex = 0;

	if (bus->name == NULL) {
		debug("%s: NULL pointer given\n", __FUNCTION__);
	} else {
		devindex = uec_miiphy_find_dev_by_name(bus->name);
		if (devindex >= 0) {
			uec_write_phy_reg(devlist[devindex], addr, reg, value);
		}
	}
	return 0;
}
Exemple #3
0
static int uec_startup(uec_private_t *uec)
{
	uec_info_t			*uec_info;
	ucc_fast_info_t			*uf_info;
	ucc_fast_private_t		*uccf;
	ucc_fast_t			*uf_regs;
	uec_t				*uec_regs;
	int				num_threads_tx;
	int				num_threads_rx;
	u32				utbipar;
	u32				length;
	u32				align;
	qe_bd_t				*bd;
	u8				*buf;
	int				i;

	if (!uec || !uec->uec_info) {
		printf("%s: uec or uec_info not initial\n", __FUNCTION__);
		return -EINVAL;
	}

	uec_info = uec->uec_info;
	uf_info = &(uec_info->uf_info);

	/* Check if Rx BD ring len is illegal */
	if ((uec_info->rx_bd_ring_len < UEC_RX_BD_RING_SIZE_MIN) || \
		(uec_info->rx_bd_ring_len % UEC_RX_BD_RING_SIZE_ALIGNMENT)) {
		printf("%s: Rx BD ring len must be multiple of 4, and > 8.\n",
			 __FUNCTION__);
		return -EINVAL;
	}

	/* Check if Tx BD ring len is illegal */
	if (uec_info->tx_bd_ring_len < UEC_TX_BD_RING_SIZE_MIN) {
		printf("%s: Tx BD ring length must not be smaller than 2.\n",
			 __FUNCTION__);
		return -EINVAL;
	}

	/* Check if MRBLR is illegal */
	if ((MAX_RXBUF_LEN == 0) || (MAX_RXBUF_LEN  % UEC_MRBLR_ALIGNMENT)) {
		printf("%s: max rx buffer length must be mutliple of 128.\n",
			 __FUNCTION__);
		return -EINVAL;
	}

	/* Both Rx and Tx are stopped */
	uec->grace_stopped_rx = 1;
	uec->grace_stopped_tx = 1;

	/* Init UCC fast */
	if (ucc_fast_init(uf_info, &uccf)) {
		printf("%s: failed to init ucc fast\n", __FUNCTION__);
		return -ENOMEM;
	}

	/* Save uccf */
	uec->uccf = uccf;

	/* Convert the Tx threads number */
	if (uec_convert_threads_num(uec_info->num_threads_tx,
					 &num_threads_tx)) {
		return -EINVAL;
	}

	/* Convert the Rx threads number */
	if (uec_convert_threads_num(uec_info->num_threads_rx,
					 &num_threads_rx)) {
		return -EINVAL;
	}

	uf_regs = uccf->uf_regs;

	/* UEC register is following UCC fast registers */
	uec_regs = (uec_t *)(&uf_regs->ucc_eth);

	/* Save the UEC register pointer to UEC private struct */
	uec->uec_regs = uec_regs;

	/* Init UPSMR, enable hardware statistics (UCC) */
	out_be32(&uec->uccf->uf_regs->upsmr, UPSMR_INIT_VALUE);

	/* Init MACCFG1, flow control disable, disable Tx and Rx */
	out_be32(&uec_regs->maccfg1, MACCFG1_INIT_VALUE);

	/* Init MACCFG2, length check, MAC PAD and CRC enable */
	out_be32(&uec_regs->maccfg2, MACCFG2_INIT_VALUE);

	/* Setup MAC interface mode */
	uec_set_mac_if_mode(uec, uec_info->enet_interface_type, uec_info->speed);

	/* Setup MII management base */
#ifndef CONFIG_eTSEC_MDIO_BUS
	uec->uec_mii_regs = (uec_mii_t *)(&uec_regs->miimcfg);
#else
	uec->uec_mii_regs = (uec_mii_t *) CONFIG_MIIM_ADDRESS;
#endif

	/* Setup MII master clock source */
	qe_set_mii_clk_src(uec_info->uf_info.ucc_num);

	/* Setup UTBIPAR */
	utbipar = in_be32(&uec_regs->utbipar);
	utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;

	/* Initialize UTBIPAR address to CONFIG_UTBIPAR_INIT_TBIPA for ALL UEC.
	 * This frees up the remaining SMI addresses for use.
	 */
	utbipar |= CONFIG_UTBIPAR_INIT_TBIPA << UTBIPAR_PHY_ADDRESS_SHIFT;
	out_be32(&uec_regs->utbipar, utbipar);

	/* Configure the TBI for SGMII operation */
	if ((uec->uec_info->enet_interface_type == PHY_INTERFACE_MODE_SGMII) &&
	   (uec->uec_info->speed == SPEED_1000)) {
		uec_write_phy_reg(uec->dev, uec_regs->utbipar,
			ENET_TBI_MII_ANA, TBIANA_SETTINGS);

		uec_write_phy_reg(uec->dev, uec_regs->utbipar,
			ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);

		uec_write_phy_reg(uec->dev, uec_regs->utbipar,
			ENET_TBI_MII_CR, TBICR_SETTINGS);
	}

	/* Allocate Tx BDs */
	length = ((uec_info->tx_bd_ring_len * SIZEOFBD) /
		 UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) *
		 UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
	if ((uec_info->tx_bd_ring_len * SIZEOFBD) %
		 UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) {
		length += UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
	}

	align = UEC_TX_BD_RING_ALIGNMENT;
	uec->tx_bd_ring_offset = (u32)malloc((u32)(length + align));
	if (uec->tx_bd_ring_offset != 0) {
		uec->p_tx_bd_ring = (u8 *)((uec->tx_bd_ring_offset + align)
						 & ~(align - 1));
	}

	/* Zero all of Tx BDs */
	memset((void *)(uec->tx_bd_ring_offset), 0, length + align);

	/* Allocate Rx BDs */
	length = uec_info->rx_bd_ring_len * SIZEOFBD;
	align = UEC_RX_BD_RING_ALIGNMENT;
	uec->rx_bd_ring_offset = (u32)(malloc((u32)(length + align)));
	if (uec->rx_bd_ring_offset != 0) {
		uec->p_rx_bd_ring = (u8 *)((uec->rx_bd_ring_offset + align)
							 & ~(align - 1));
	}

	/* Zero all of Rx BDs */
	memset((void *)(uec->rx_bd_ring_offset), 0, length + align);

	/* Allocate Rx buffer */
	length = uec_info->rx_bd_ring_len * MAX_RXBUF_LEN;
	align = UEC_RX_DATA_BUF_ALIGNMENT;
	uec->rx_buf_offset = (u32)malloc(length + align);
	if (uec->rx_buf_offset != 0) {
		uec->p_rx_buf = (u8 *)((uec->rx_buf_offset + align)
						 & ~(align - 1));
	}

	/* Zero all of the Rx buffer */
	memset((void *)(uec->rx_buf_offset), 0, length + align);

	/* Init TxBD ring */
	bd = (qe_bd_t *)uec->p_tx_bd_ring;
	uec->txBd = bd;

	for (i = 0; i < uec_info->tx_bd_ring_len; i++) {
		BD_DATA_CLEAR(bd);
		BD_STATUS_SET(bd, 0);
		BD_LENGTH_SET(bd, 0);
		bd ++;
	}
	BD_STATUS_SET((--bd), TxBD_WRAP);

	/* Init RxBD ring */
	bd = (qe_bd_t *)uec->p_rx_bd_ring;
	uec->rxBd = bd;
	buf = uec->p_rx_buf;
	for (i = 0; i < uec_info->rx_bd_ring_len; i++) {
		BD_DATA_SET(bd, buf);
		BD_LENGTH_SET(bd, 0);
		BD_STATUS_SET(bd, RxBD_EMPTY);
		buf += MAX_RXBUF_LEN;
		bd ++;
	}
	BD_STATUS_SET((--bd), RxBD_WRAP | RxBD_EMPTY);

	/* Init global Tx parameter RAM */
	uec_init_tx_parameter(uec, num_threads_tx);

	/* Init global Rx parameter RAM */
	uec_init_rx_parameter(uec, num_threads_rx);

	/* Init ethernet Tx and Rx parameter command */
	if (uec_issue_init_enet_rxtx_cmd(uec, num_threads_tx,
					 num_threads_rx)) {
		printf("%s issue init enet cmd failed\n", __FUNCTION__);
		return -ENOMEM;
	}

	return 0;
}