📄 emac_phy.c
字号:
mii_serial_write(0); // dumy clock mii_serial_write(0); // dumy clock return(value);}/******************************************* Write MII register* phyad -> physical address* regad -> register address* value -> value to be write***************************************** */void mii_write(unsigned char phyad,unsigned char regad,unsigned int value){ unsigned int i; char bit; mii_pre_st(); // PRE+ST mii_serial_write(0); // OP mii_serial_write(1); for (i=0;i<5;i++) { // PHYAD bit= ((phyad>>(4-i)) & 0x01) ? 1 :0 ; mii_serial_write(bit); } for (i=0;i<5;i++) { // REGAD bit= ((regad>>(4-i)) & 0x01) ? 1 :0 ; mii_serial_write(bit); } mii_serial_write(1); // TA_1 mii_serial_write(0); // TA_0 for (i=0;i<16;i++) { // OUT DATA bit= ((value>>(15-i)) & 0x01) ? 1 : 0 ; mii_serial_write(bit); } mii_serial_write(0); // dumy clock mii_serial_write(0); // dumy clock}/* NOTES * The instruction set of the 93C66/56/46/26/06 chips are as follows: * * Start OP * * Function Bit Code Address** Data Description * ------------------------------------------------------------------- * READ 1 10 A7 - A0 Reads data stored in memory, * starting at specified address * EWEN 1 00 11XXXXXX Write enable must precede * all programming modes * ERASE 1 11 A7 - A0 Erase register A7A6A5A4A3A2A1A0 * WRITE 1 01 A7 - A0 D15 - D0 Writes register * ERAL 1 00 10XXXXXX Erase all registers * WRAL 1 00 01XXXXXX D15 - D0 Writes to all registers * EWDS 1 00 00XXXXXX Disables all programming * instructions * *Note: A value of X for address is a don't care condition. * **Note: There are 8 address bits for the 93C56/66 chips unlike * the 93C46/26/06 chips which have 6 address bits. * * The 93Cx6 has a four wire interface: clock, chip select, data in, and * data out.While the ADM6996 uning three interface: clock, chip select,and data line. * The input and output are the same pin. ADM6996 can only recognize the write cmd. * In order to perform above functions, you need * 1. to enable the chip select . * 2. send one clock of dummy clock * 3. send start bit and opcode * 4. send 8 bits address and 16 bits data * 5. to disable the chip select. * Jason Lee 2003/07/30 *//***************************************//* define GPIO module base address *//***************************************/#define GPIO_EECS 0x04000000 /* EECS: GPIO[22] */#define GPIO_MISO 0x02000000 /* EEDI: GPIO[30] receive from 6996*/ #define GPIO_EECK 0x01000000 /* EECK: GPIO[31] *//************************************************************** SPI protocol for ADM6996 control**************************************************************/#define SPI_OP_LEN 0x03 // the length of start bit and opcode#define SPI_OPWRITE 0X05 // write#define SPI_OPREAD 0X06 // read#define SPI_OPERASE 0X07 // erase#define SPI_OPWTEN 0X04 // write enable#define SPI_OPWTDIS 0X04 // write disable#define SPI_OPERSALL 0X04 // erase all#define SPI_OPWTALL 0X04 // write all// #define CONFIG_ADM_6996 1 // move to board_config.h// #define CONFIG_ADM_6999 1 // move to board_config.h#define SPI_ADD_LEN 8 // bits of Address#define SPI_DAT_LEN 16 // bits of Data#define ADM6996_PORT_NO 6 // the port number of ADM6996#define ADM6999_PORT_NO 9 // the port number of ADM6999#define ADM699X_PORT_NO ADM6996_PORT_NO#define PORT0 0#define PORT1 1#define PORT2 2#define PORT3 3#define PORT4 4#define PORT5 5/****************************************//* Function Declare *//****************************************//*void SPI_write(unsigned char addr,unsigned int value);unsigned int SPI_read(unsigned char table,unsigned char addr);void SPI_write_bit(char bit_EEDO);unsigned int SPI_read_bit(void);void SPI_default(int vlan_enabled);void SPI_reset(unsigned char rstype,unsigned char port_cnt);void SPI_pre_st(void);void SPI_CS_enable(unsigned char enable);void SPI_Set_VLAN(unsigned char LAN,unsigned int port_mask);void SPI_Set_tag(unsigned int port,unsigned tag);void SPI_Set_PVID(unsigned int PVID,unsigned int port_mask);void SPI_mac_lock(unsigned int port, unsigned char lock);void SPI_get_port_state(unsigned int port);void SPI_port_enable(unsigned int port,unsigned char enable);void SPI_get_status(unsigned int port);*/struct PORT_CONFIG{ unsigned char auto_negotiation; // 0:Disable 1:Enable unsigned char speed; // 0:10M 1:100M unsigned char duplex; // 0:Half 1:Full duplex unsigned char Tag; // 0:Untag 1:Tag unsigned char port_disable; // 0:port enable 1:disable unsigned char pvid; // port VLAN ID 0001 unsigned char mdix; // Crossover judgement. 0:Disable 1:Enable unsigned char mac_lock; // MAC address Lock 0:Disable 1:Enable};struct PORT_STATUS{ unsigned char link; // 0:not link 1:link established unsigned char speed; // 0:10M 1:100M unsigned char duplex; // 0:Half 1:Full duplex unsigned char flow_ctl; // 0:flow control disable 1:enable unsigned char mac_lock; // MAC address Lock 0:Disable 1:Enable unsigned char port_disable; // 0:port enable 1:disable // Serial Management unsigned long rx_pac_count; //receive packet count unsigned long rx_pac_byte; //receive packet byte count unsigned long tx_pac_count; //transmit packet count unsigned long tx_pac_byte; //transmit packet byte count unsigned long collision_count; //error count unsigned long rx_pac_count_overflow; //overflow flag unsigned long rx_pac_byte_overflow; unsigned long tx_pac_count_overflow; unsigned long tx_pac_byte_overflow; unsigned long collision_count_overflow; unsigned long error_count ; unsigned long error_count_overflow;};struct PORT_CONFIG port_config[ADM6996_PORT_NO]; // 0~3:LAN , 4:WAN , 5:MIIstatic struct PORT_STATUS port_state[ADM6996_PORT_NO];/******************************************* SPI_write* addr -> Write Address* value -> value to be write***************************************** */void SPI_write(unsigned char addr,unsigned int value){ int i,ad1; char bit, status;#ifndef LPC_IT8712 ad1 = (GPIO_BASE_ADDR + GPIO_DATA_CLEAR); writel(GPIO_MISO,ad1); /* set MISO to 0 */#endif SPI_CS_enable(1); SPI_write_bit(0); //dummy clock //send write command (0x05) for(i=SPI_OP_LEN-1;i>=0;i--) { bit = (SPI_OPWRITE>>i)& 0x01; SPI_write_bit(bit); } // send 8 bits address (MSB first, LSB last) for(i=SPI_ADD_LEN-1;i>=0;i--) { bit = (addr>>i)& 0x01; SPI_write_bit(bit); } // send 16 bits data (MSB first, LSB last) for(i=SPI_DAT_LEN-1;i>=0;i--) { bit = (value>>i)& 0x01; SPI_write_bit(bit); } SPI_CS_enable(0); // CS low for(i=0;i<0xFFF;i++) ;#ifdef LPC_IT8712 status = inb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF); status &= ~(ADM_EDIO) ; //EDIO low outb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF,status);#endif }/************************************* SPI_write_bit* bit_EEDO -> 1 or 0 to be written************************************/void SPI_write_bit(char bit_EEDO){#ifndef LPC_IT8712 unsigned int addr; unsigned int value; addr = (GPIO_BASE_ADDR + GPIO_PIN_DIR); value = readl(addr) |GPIO_EECK |GPIO_MISO ; // set EECK/MISO Pin to output writel(value,addr); if(bit_EEDO) { addr = (GPIO_BASE_ADDR + GPIO_DATA_SET); writel(GPIO_MISO,addr); // set MISO to 1 writel(GPIO_EECK,addr); // set EECK to 1 addr = (GPIO_BASE_ADDR + GPIO_DATA_CLEAR); writel(GPIO_EECK,addr); // set EECK to 0 } else { addr = (GPIO_BASE_ADDR + GPIO_DATA_CLEAR); writel(GPIO_MISO,addr); // set MISO to 0 addr = (GPIO_BASE_ADDR + GPIO_DATA_SET); writel(GPIO_EECK,addr); // set EECK to 1 addr = (GPIO_BASE_ADDR + GPIO_DATA_CLEAR); writel(GPIO_EECK,addr); // set EECK to 0 }#else unsigned char iomode,status; iomode = LPCGetConfig(LDN_GPIO, 0xc8 + BASE_OFF); iomode |= (ADM_EECK|ADM_EDIO|ADM_EECS) ; // Set EECK,EDIO,EECS output LPCSetConfig(LDN_GPIO, 0xc8 + BASE_OFF, iomode); if(bit_EEDO) { status = inb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF); status |= ADM_EDIO ; //EDIO high outb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF,status); } else { status = inb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF); status &= ~(ADM_EDIO) ; //EDIO low outb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF,status); } status |= ADM_EECK ; //EECK high outb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF,status); status &= ~(ADM_EECK) ; //EECK low outb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF,status);#endif}/*********************************************************************** read a bit from ADM6996 register***********************************************************************/unsigned int SPI_read_bit(void) // read data from{#ifndef LPC_IT8712 unsigned int addr; unsigned int value; addr = (GPIO_BASE_ADDR + GPIO_PIN_DIR); value = readl(addr) & (~GPIO_MISO); // set EECK to output and MISO to input writel(value,addr); addr =(GPIO_BASE_ADDR + GPIO_DATA_SET); writel(GPIO_EECK,addr); // set EECK to 1 addr = (GPIO_BASE_ADDR + GPIO_DATA_CLEAR); writel(GPIO_EECK,addr); // set EECK to 0 addr = (GPIO_BASE_ADDR + GPIO_DATA_IN); value = readl(addr) ; value = value >> 25; return value ;#else unsigned char iomode,status; unsigned int value ; iomode = LPCGetConfig(LDN_GPIO, 0xc8 + BASE_OFF); iomode &= ~(ADM_EDIO) ; // Set EDIO input iomode |= (ADM_EECS|ADM_EECK) ; // Set EECK,EECS output LPCSetConfig(LDN_GPIO, 0xc8 + BASE_OFF, iomode); status = inb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF); status |= ADM_EECK ; //EECK high outb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF,status); status &= ~(ADM_EECK) ; //EECK low outb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF,status); value = inb(LPC_BASE_ADDR + IT8712_GPIO_BASE + BASE_OFF); value = value>>2 ; value &= 0x01; return value ;#endif}/******************************************* SPI_default* EEPROM content default value*******************************************/void SPI_default(int vlan_enabled){ int i;#ifdef CONFIG_ADM_6999 if(chip_id >= 0xA3 || !vlan_enabled) { //for A3 and later chip, redboot did not setup vlan for(i=1;i<8;i++) SPI_write(i,0x840F); // enable auto-crossover //SPI_write(0x08,0x842F); SPI_write(0x08,0x840F); return ; } else { SPI_write(0x11,0xFF30); for(i=1;i<8;i++) SPI_write(i,0x840F); SPI_write(0x08,0x880F); //port 8 Untag, PVID=2 SPI_write(0x09,0x881D); //port 9 Tag, PVID=2 ,10M SPI_write(0x14,0x017F); //Group 0~6,8 as VLAN 1 SPI_write(0x15,0x0180); //Group 7,8 as VLAN 2 }#endif#ifdef CONFIG_ADM_6996 if(chip_id > =0xA3 || !vlan_enabled) { //for A3 and later chip, redboot did not setup vlan for(i=1;i<8;i+=2) SPI_write(i,0x840F); // enable auto-crossover //SPI_write(0x08,0x842F); SPI_write(0x08,0x840F); return ; } else { SPI_write(0x11,0xFF30); SPI_write(0x01,0x840F); //port 0~3 Untag ,PVID=1 ,100M ,duplex SPI_write(0x03,0x840F); SPI_write(0x05,0x840F); SPI_write(0x07,0x840F); SPI_write(0x08,0x880F); //port 4 Untag, PVID=2 SPI_write(0x09,0x881D); //port 5 Tag, PVID=2 ,10M SPI_write(0x14,0x0155); //Group 0~3,5 as VLAN 1 SPI_write(0x15,0x0180); //Group 4,5 as VLAN 2 }#endif for(i=0x16;i<=0x22;i++) SPI_write((unsigned char)i,0x0000); // clean VLAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -