/* * 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; }
/* * 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; }
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; }