📄 c5471_ethernet.c
字号:
if (i + j < nbytes) { sprintf(&line[strlen(line)], "%02x", buffer[i+j] ); } else { strcpy(&line[strlen(line)], " "); } if (j == 7 || j == 15) { strcpy(&line[strlen(line)], " "); } } for ( j = 0; j < 16; j++) { if (i + j < nbytes) { ch = buffer[i+j]; sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.'); } if (j == 7 || j == 15) { strcpy(&line[strlen(line)], " "); } } ndbg("%s\n", line); }#endif}#else# define c5471_dumpbuffer(buffer,nbytes)#endif/**************************************************************************** * Name: c5471_mdtxbit * * Description * A helper routine used when serially communicating with the c547X's * external ethernet transeiver device. GPIO pins are connected to the * transeiver's MDCLK and MDIO pins and are used to accomplish the serial * comm. * * protocol: * ___________ * MDCLK ________/ \_ * ________:____ * MDIO <________:____>-------- * : * ^ * Pin state internalized * ****************************************************************************/static void c5471_mdtxbit (int bit_state){ /* Note: any non-zero "bit_state" supplied by the caller means we should clk a "1" * out the MDIO pin. */ /* Config MDIO as output pin. */ putreg32((getreg32(GPIO_CIO) & ~GPIO_CIO_MDIO), GPIO_CIO); /* Select the the bit output state */ if (bit_state) { /* set MDIO state high. */ putreg32((getreg32(GPIO_IO) | GPIO_CIO_MDIO), GPIO_IO); } else { /* set MDIO state low. */ putreg32((getreg32(GPIO_IO) & ~GPIO_CIO_MDIO), GPIO_IO); } nop(); nop(); nop(); nop(); /* MDCLK rising edge */ putreg32((getreg32(GPIO_IO) | GPIO_IO_MDCLK), GPIO_IO); nop(); nop(); /* release MDIO */ putreg32((getreg32(GPIO_CIO) | GPIO_CIO_MDIO), GPIO_CIO); nop(); nop(); /* MDCLK falling edge. */ putreg32((getreg32(GPIO_IO) & ~GPIO_IO_MDCLK), GPIO_IO);}/**************************************************************************** * Name: c5471_mdrxbit * * Description * A helper routine used when serially communicating with the c547X's * external ethernet transeiver device. GPIO pins are connected to the * transeiver's MDCLK and MDIO pins and are used to accomplish the serial * comm. * * protocol: * ___________ * MDCLK ________/ \_ * _______:_____ * MDIO _______:_____>-------- * : * ^ * pin state sample point * ****************************************************************************/static int c5471_mdrxbit (void){ register volatile uint32 bit_state; /* config MDIO as input pin. */ putreg32((getreg32(GPIO_CIO) | GPIO_CIO_MDIO), GPIO_CIO); /* Make sure the MDCLK is low */ putreg32((getreg32(GPIO_IO) & ~GPIO_IO_MDCLK), GPIO_IO); nop(); nop(); nop(); nop(); /* Sample MDIO */ bit_state = getreg32(GPIO_IO) & GPIO_CIO_MDIO; /* MDCLK rising edge */ putreg32((getreg32(GPIO_IO) | GPIO_IO_MDCLK), GPIO_IO); nop(); nop(); nop(); nop(); /* MDCLK falling edge. */ putreg32((getreg32(GPIO_IO)&~GPIO_IO_MDCLK), GPIO_IO); /* MDCLK falling edge */ if (bit_state) { return 1; } else { return OK; }}/**************************************************************************** * Name: c5471_mdwrite * * Description * A helper routine used when serially communicating with the c547X's * external ethernet transeiver device. GPIO pins are connected to the * transeiver's MDCLK and MDIO pins and are used to accomplish the serial * comm. * ****************************************************************************/static void c5471_mdwrite (int adr, int reg, int data){ int i; /* preamble: 11111111111111111111111111111111 */ for (i = 0; i < 32; i++) { c5471_mdtxbit(1); } /* start of frame: 01 */ c5471_mdtxbit(0); c5471_mdtxbit(1); /* operation code: 01 - write */ c5471_mdtxbit(0); c5471_mdtxbit(1); /* PHY device address: AAAAA, msb first */ for (i = 0; i < 5; i++) { c5471_mdtxbit(adr & 0x10); adr = adr << 1; } /* MII register address: RRRRR, msb first */ for (i = 0; i < 5; i++) { c5471_mdtxbit(reg & 0x10); reg = reg << 1; } /* Turnaround time: ZZ */ c5471_mdtxbit(1); c5471_mdtxbit(0); /* data: DDDDDDDDDDDDDDDD, msb first */ for (i = 0; i < 16; i++) { c5471_mdtxbit(data & 0x8000); data = data << 1; }}/**************************************************************************** * Name: c5471_mdread * * Description * A helper routine used when serially communicating with the c547X's * external ethernet transeiver device. GPIO pins are connected to the * transeiver's MDCLK and MDIO pins and are used to accomplish the serial * comm. * ****************************************************************************/static int c5471_mdread (int adr, int reg){ int i; int data = 0; /* preamble: 11111111111111111111111111111111 */ for (i = 0; i < 32; i++) { c5471_mdtxbit(1); } /* start of frame: 01 */ c5471_mdtxbit(0); c5471_mdtxbit(1); /* operation code: 10 - read */ c5471_mdtxbit(1); c5471_mdtxbit(0); /* PHY device address: AAAAA, msb first */ for (i = 0; i < 5; i++) { c5471_mdtxbit(adr & 0x10); adr = adr << 1; } /* MII register address: RRRRR, msb first */ for (i = 0; i < 5; i++) { c5471_mdtxbit(reg & 0x10); reg = reg << 1; } /* turnaround time: ZZ */ c5471_mdrxbit(); c5471_mdrxbit(); /* PHY should drive a 0 */ /* data: DDDDDDDDDDDDDDDD, msb first */ for (i = 0; i < 16; i++) { data = data << 1; data |= c5471_mdrxbit(); } return data;}/**************************************************************************** * Name: c5471_phyinit * * Description * The c547X EVM board uses a Lucent LU3X31T-T64 transeiver device to * handle the physical layer (PHY). It's a h/w block that on the one end * offers a Media Independent Interface (MII) which is connected to the * Ethernet Interface Module (EIM) internal to the C547x and on the other * end offers either the 10baseT or 100baseT electrical interface connecting * to an RJ45 onboard network connector. The PHY transeiver has several * internal registers allowing host configuration and status access. These * internal registers are accessable by clocking serial data in/out of the * MDIO pin of the LU3X31T-T64 chip. For c547X, the MDC and the MDIO pins * are connected to the C547x GPIO15 and GPIO14 pins respectivley. Host * software twiddles the GPIO pins appropriately to get data serially into * and out of the chip. This is typically a one time operation at boot and * normal operation of the transeiver involves EIM/Transeiver interaction at * the other pins of the transeiver chip and doesn't require host intervention * at the MDC and MDIO pins. * ****************************************************************************/#if (CONFIG_C5471_ETHERNET_PHY == ETHERNET_PHY_LU3X31T_T64)static int c5471_phyinit (void){ int phyid; int status; /* Next, Setup GPIO pins to talk serially to the Lucent transeiver chip */ /* enable gpio bits 15,14 */ putreg32((getreg32(GPIO_EN) | 0x0000C000), GPIO_EN); /* config gpio(15); out -> MDCLK */ putreg32((getreg32(GPIO_CIO) & ~0x00008000), GPIO_CIO); /* config gpio(14); in <- MDIO */ putreg32((getreg32(GPIO_CIO) | 0x00004000), GPIO_CIO); /* initial pin state; MDCLK = 0 */ putreg32((getreg32(GPIO_IO) & 0x000F3FFF), GPIO_IO); /* Next, request a chip reset */ c5471_mdwrite(0, MD_PHY_CONTROL_REG, 0x8000); while (c5471_mdread(0, MD_PHY_CONTROL_REG) & 0x8000) { /* wait for chip reset to complete */ } /* Next, Read out the chip ID */ phyid = (c5471_mdread(0, MD_PHY_MSB_REG) << 16) | c5471_mdread(0, MD_PHY_LSB_REG); if (phyid != LU3X31_T64_PHYID) { ndbg("Unrecognized PHY ID: %08x\n", phyid); return ERROR; } /* Next, Set desired network rate, 10BaseT, 100BaseT, or auto. */#ifdef CONFIG_NET_C5471_AUTONEGOTIATION ndbg("Setting PHY Transceiver for Autonegotiation\n"); c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_AUTONEG);#endif #ifdef CONFIG_NET_C5471_BASET100 ndbg("Setting PHY Transceiver for 100BaseT FullDuplex\n"); c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_100MBIT_FULLDUP);#endif #ifdef CONFIG_NET_C5471_BASET10 ndbg("Setting PHY Transceiver for 10BaseT FullDuplex\n"); c5471_mdwrite(0, MD_PHY_CONTROL_REG, MODE_10MBIT_FULLDUP);#endif status = c5471_mdread(0, MD_PHY_CTRL_STAT_REG); return status;}#elif (CONFIG_C5471_ETHERNET_PHY == ETHERNET_PHY_AC101L)static int c5471_phyinit (void){ int phyid; int status; /* Next, Setup GPIO pins to talk serially to the Lucent transeiver chip */ putreg32((getreg32(GPIO_EN) | 0x0000C000), GPIO_EN); /* enable gpio bits 15,14 */ putreg32((getreg32(GPIO_CIO) & ~0x00008000), GPIO_CIO); /* config gpio(15); out -> MDCLK */ putreg32((getreg32(GPIO_CIO) | 0x00004000), GPIO_CIO); /* config gpio(14); in <- MDIO */ putreg32((getreg32(GPIO_IO) & 0x000F3FFF), GPIO_IO); /* initial pin state; MDCLK = 0 */ return 1;}#else# define c5471_phyinit()# if defined(CONFIG_C5471_ETHERNET_PHY)# error "CONFIG_C5471_ETHERNET_PHY value not recognized"# else# warning "CONFIG_C5471_ETHERNET_PHY not defined -- assumed NO PHY"# endif#endif/**************************************************************************** * Name: c5471_inctxcpu * * Description * ****************************************************************************/static inline void c5471_inctxcpu(struct c5471_driver_s *c5471){ if (EIM_TXDESC_WRAP_NEXT & getreg32(c5471->c_txcpudesc)) { /* Loop back around to base of descriptor queue */ c5471->c_txcpudesc = getreg32(EIM_CPU_TXBA) + EIM_RAM_START; } else { c5471->c_txcpudesc += 2*sizeof(uint32); } nvdbg("TX CPU desc: %08x\n", c5471->c_txcpudesc);}/**************************************************************************** * Name: c5471_incrxcpu * * Description * ****************************************************************************/static inline void c5471_incrxcpu(struct c5471_driver_s *c5471)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -