📄 tsec.c
字号:
{MIIM_CONTROL, MIIM_CONTROL_INIT, NULL}, {miim_end,} }, (struct phy_cmd[]){ /* startup */ /* Status is read once to clear old link state */ {MIIM_STATUS, miim_read, NULL}, /* Auto-negotiate */ {MIIM_STATUS, miim_read, &mii_parse_sr}, {MIIM_88E1111_PHY_LED_CONTROL, MIIM_88E1111_PHY_LED_DIRECT, NULL}, /* Read the Status */ {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr}, {miim_end,} }, (struct phy_cmd[]){ /* shutdown */ {miim_end,} },};struct phy_info phy_info_cis8204 = { 0x3f11, "Cicada Cis8204", 6, (struct phy_cmd[]){ /* config */ /* Override PHY config settings */ {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, /* Configure some basic stuff */ {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT, &mii_cis8204_fixled}, {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, &mii_cis8204_setmode}, {miim_end,} }, (struct phy_cmd[]){ /* startup */ /* Read the Status (2x to make sure link is right) */ {MIIM_STATUS, miim_read, NULL}, /* Auto-negotiate */ {MIIM_STATUS, miim_read, &mii_parse_sr}, /* Read the status */ {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201}, {miim_end,} }, (struct phy_cmd[]){ /* shutdown */ {miim_end,} },};/* Cicada 8201 */struct phy_info phy_info_cis8201 = { 0xfc41, "CIS8201", 4, (struct phy_cmd[]){ /* config */ /* Override PHY config settings */ {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, /* Set up the interface mode */ {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL}, /* Configure some basic stuff */ {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, {miim_end,} }, (struct phy_cmd[]){ /* startup */ /* Read the Status (2x to make sure link is right) */ {MIIM_STATUS, miim_read, NULL}, /* Auto-negotiate */ {MIIM_STATUS, miim_read, &mii_parse_sr}, /* Read the status */ {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201}, {miim_end,} }, (struct phy_cmd[]){ /* shutdown */ {miim_end,} },};struct phy_info phy_info_VSC8244 = { 0x3f1b, "Vitesse VSC8244", 6, (struct phy_cmd[]){ /* config */ /* Override PHY config settings */ /* Configure some basic stuff */ {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, {miim_end,} }, (struct phy_cmd[]){ /* startup */ /* Read the Status (2x to make sure link is right) */ {MIIM_STATUS, miim_read, NULL}, /* Auto-negotiate */ {MIIM_STATUS, miim_read, &mii_parse_sr}, /* Read the status */ {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244}, {miim_end,} }, (struct phy_cmd[]){ /* shutdown */ {miim_end,} },};struct phy_info phy_info_dm9161 = { 0x0181b88, "Davicom DM9161E", 4, (struct phy_cmd[]){ /* config */ {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL}, /* Do not bypass the scrambler/descrambler */ {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL}, /* Clear 10BTCSR to default */ {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL}, /* Configure some basic stuff */ {MIIM_CONTROL, MIIM_CR_INIT, NULL}, /* Restart Auto Negotiation */ {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL}, {miim_end,} }, (struct phy_cmd[]){ /* startup */ /* Status is read once to clear old link state */ {MIIM_STATUS, miim_read, NULL}, /* Auto-negotiate */ {MIIM_STATUS, miim_read, &mii_parse_sr}, /* Read the status */ {MIIM_DM9161_SCSR, miim_read, &mii_parse_dm9161_scsr}, {miim_end,} }, (struct phy_cmd[]){ /* shutdown */ {miim_end,} },};uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv){ unsigned int speed; if (priv->link) { speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK; switch (speed) { case MIIM_LXT971_SR2_10HDX: priv->speed = 10; priv->duplexity = 0; break; case MIIM_LXT971_SR2_10FDX: priv->speed = 10; priv->duplexity = 1; break; case MIIM_LXT971_SR2_100HDX: priv->speed = 100; priv->duplexity = 0; default: priv->speed = 100; priv->duplexity = 1; break; } } else { priv->speed = 0; priv->duplexity = 0; } return 0;}static struct phy_info phy_info_lxt971 = { 0x0001378e, "LXT971", 4, (struct phy_cmd[]){ /* config */ {MIIM_CR, MIIM_CR_INIT, mii_cr_init}, /* autonegotiate */ {miim_end,} }, (struct phy_cmd[]){ /* startup - enable interrupts */ /* { 0x12, 0x00f2, NULL }, */ {MIIM_STATUS, miim_read, NULL}, {MIIM_STATUS, miim_read, &mii_parse_sr}, {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2}, {miim_end,} }, (struct phy_cmd[]){ /* shutdown - disable interrupts */ {miim_end,} },};/* Parse the DP83865's link and auto-neg status register for speed and duplex * information */uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv){ switch (mii_reg & MIIM_DP83865_SPD_MASK) { case MIIM_DP83865_SPD_1000: priv->speed = 1000; break; case MIIM_DP83865_SPD_100: priv->speed = 100; break; default: priv->speed = 10; break; } if (mii_reg & MIIM_DP83865_DPX_FULL) priv->duplexity = 1; else priv->duplexity = 0; return 0;}struct phy_info phy_info_dp83865 = { 0x20005c7, "NatSemi DP83865", 4, (struct phy_cmd[]){ /* config */ {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL}, {miim_end,} }, (struct phy_cmd[]){ /* startup */ /* Status is read once to clear old link state */ {MIIM_STATUS, miim_read, NULL}, /* Auto-negotiate */ {MIIM_STATUS, miim_read, &mii_parse_sr}, /* Read the link and auto-neg status */ {MIIM_DP83865_LANR, miim_read, &mii_parse_dp83865_lanr}, {miim_end,} }, (struct phy_cmd[]){ /* shutdown */ {miim_end,} },};struct phy_info *phy_info[] = {#if 0 &phy_info_cis8201,#endif &phy_info_cis8204, &phy_info_M88E1011S, &phy_info_M88E1111S, &phy_info_M88E1145, &phy_info_dm9161, &phy_info_lxt971, &phy_info_VSC8244, &phy_info_dp83865, NULL};/* Grab the identifier of the device's PHY, and search through * all of the known PHYs to see if one matches. If so, return * it, if not, return NULL */struct phy_info *get_phy_info(struct eth_device *dev){ struct tsec_private *priv = (struct tsec_private *)dev->priv; uint phy_reg, phy_ID; int i; struct phy_info *theInfo = NULL; /* Grab the bits from PHYIR1, and put them in the upper half */ phy_reg = read_phy_reg(priv, MIIM_PHYIR1); phy_ID = (phy_reg & 0xffff) << 16; /* Grab the bits from PHYIR2, and put them in the lower half */ phy_reg = read_phy_reg(priv, MIIM_PHYIR2); phy_ID |= (phy_reg & 0xffff); /* loop through all the known PHY types, and find one that */ /* matches the ID we read from the PHY. */ for (i = 0; phy_info[i]; i++) { if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) theInfo = phy_info[i]; } if (theInfo == NULL) { printf("%s: PHY id %x is not supported!\n", dev->name, phy_ID); return NULL; } else { debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID); } return theInfo;}/* Execute the given series of commands on the given device's * PHY, running functions as necessary */void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd){ int i; uint result; volatile tsec_t *phyregs = priv->phyregs; phyregs->miimcfg = MIIMCFG_RESET; phyregs->miimcfg = MIIMCFG_INIT_VALUE; while (phyregs->miimind & MIIMIND_BUSY) ; for (i = 0; cmd->mii_reg != miim_end; i++) { if (cmd->mii_data == miim_read) { result = read_phy_reg(priv, cmd->mii_reg); if (cmd->funct != NULL) (*(cmd->funct)) (result, priv); } else { if (cmd->funct != NULL) result = (*(cmd->funct)) (cmd->mii_reg, priv); else result = cmd->mii_data; write_phy_reg(priv, cmd->mii_reg, result); } cmd++; }}/* Relocate the function pointers in the phy cmd lists */static void relocate_cmds(void){ struct phy_cmd **cmdlistptr; struct phy_cmd *cmd; int i, j, k; for (i = 0; phy_info[i]; i++) { /* First thing's first: relocate the pointers to the * PHY command structures (the structs were done) */ phy_info[i] = (struct phy_info *)((uint) phy_info[i] + gd->reloc_off); phy_info[i]->name += gd->reloc_off; phy_info[i]->config = (struct phy_cmd *)((uint) phy_info[i]->config + gd->reloc_off); phy_info[i]->startup = (struct phy_cmd *)((uint) phy_info[i]->startup + gd->reloc_off); phy_info[i]->shutdown = (struct phy_cmd *)((uint) phy_info[i]->shutdown + gd->reloc_off); cmdlistptr = &phy_info[i]->config; j = 0; for (; cmdlistptr <= &phy_info[i]->shutdown; cmdlistptr++) { k = 0; for (cmd = *cmdlistptr; cmd->mii_reg != miim_end; cmd++) { /* Only relocate non-NULL pointers */ if (cmd->funct) cmd->funct += gd->reloc_off; k++; } j++; } } relocated = 1;}#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) \ && !defined(BITBANGMII)struct tsec_private *get_priv_for_phy(unsigned char phyaddr){ int i; for (i = 0; i < MAXCONTROLLERS; i++) { if (privlist[i]->phyaddr == phyaddr) return privlist[i]; } return NULL;}/* * Read a MII PHY register. * * Returns: * 0 on success */static int tsec_miiphy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value){ unsigned short ret; struct tsec_private *priv = get_priv_for_phy(addr); if (NULL == priv) { printf("Can't read PHY at address %d\n", addr); return -1; } ret = (unsigned short)read_phy_reg(priv, reg); *value = ret; return 0;}/* * Write a MII PHY register. * * Returns: * 0 on success */static int tsec_miiphy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value){ struct tsec_private *priv = get_priv_for_phy(addr); if (NULL == priv) { printf("Can't write PHY at address %d\n", addr); return -1; } write_phy_reg(priv, reg, value); return 0;}#endif /* defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(BITBANGMII) */#endif /* CONFIG_TSEC_ENET */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -