⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 athrs26_phy.c

📁 TP-LINK公司TL-WR941N无线路由器的Bootloader U_BOOT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
** athrs26_phy_is_fdx - Determines whether the phy ports associated with the* specified device are FULL or HALF duplex.** RETURNS:*    1  --> FULL*    0 --> HALF*/intathrs26_phy_is_fdx(int ethUnit){    int         phyUnit;    uint32_t    phyBase;    uint32_t    phyAddr;    uint16_t    phyHwStatus;    int         ii = 200;        if (ethUnit == ENET_UNIT_LAN)        return TRUE;        for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        if (athrs26_phy_is_link_alive(phyUnit)) {            phyBase = ATHR_PHYBASE(phyUnit);            phyAddr = ATHR_PHYADDR(phyUnit);            do {                phy_reg_read(phyBase, phyAddr, ATHR_PHY_SPEC_STATUS, &phyHwStatus);        	    sysMsDelay(10);            } while((!(phyHwStatus & ATHR_STATUS_RESOVLED)) && --ii);            if (phyHwStatus & ATHER_STATUS_FULL_DEPLEX)                return TRUE;        }    }    return FALSE;}/******************************************************************************** athrs26_phy_speed - Determines the speed of phy ports associated with the* specified device.** RETURNS:*               AG7100_PHY_SPEED_10T, AG7100_PHY_SPEED_100TX;*               AG7100_PHY_SPEED_1000T;*/BOOLathrs26_phy_speed(int ethUnit){    int         phyUnit;    uint16_t    phyHwStatus;    uint32_t    phyBase;    uint32_t    phyAddr;    int         ii = 200;        if (ethUnit == ENET_UNIT_LAN)        return _100BASET;    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        if (athrs26_phy_is_link_alive(phyUnit)) {            phyBase = ATHR_PHYBASE(phyUnit);            phyAddr = ATHR_PHYADDR(phyUnit);                        do {                phy_reg_read(phyBase, phyAddr,                                            ATHR_PHY_SPEC_STATUS, &phyHwStatus);                sysMsDelay(10);            }while((!(phyHwStatus & ATHR_STATUS_RESOVLED)) && --ii);            phyHwStatus = ((phyHwStatus & ATHER_STATUS_LINK_MASK) >>                           ATHER_STATUS_LINK_SHIFT);            switch(phyHwStatus) {            case 0:                return _10BASET;            case 1:                return _100BASET;            case 2:                return _1000BASET;            default:                DRV_PRINT(DRV_DEBUG_PHYERROR, ("Unkown speed read!\n"));            }        }    }    return _10BASET;}/******************************************************************************* athr_phy_is_up -- checks for significant changes in PHY state.** A "significant change" is:*     dropped link (e.g. ethernet cable unplugged) OR*     autonegotiation completed + link (e.g. ethernet cable plugged in)** When a PHY is plugged in, phyLinkGained is called.* When a PHY is unplugged, phyLinkLost is called.*/intathrs26_phy_is_up(int ethUnit){    int             phyUnit;    uint16_t        phyHwStatus;    athrPhyInfo_t  *lastStatus;    int             linkCount   = 0;    int             lostLinks   = 0;    int             gainedLinks = 0;    uint32_t        phyBase;    uint32_t        phyAddr;#ifdef CFG_ATHRHDR_REG    /* if using header to config s26, the link of MAC0 should always be up */    if (ethUnit == ENET_UNIT_LAN)        return 1;#endif    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {            continue;        }        phyBase = ATHR_PHYBASE(phyUnit);        phyAddr = ATHR_PHYADDR(phyUnit);        lastStatus = &athrPhyInfo[phyUnit];        phy_reg_read(phyBase, phyAddr, ATHR_PHY_SPEC_STATUS, &phyHwStatus);        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */            /* See if we've lost link */            if (phyHwStatus & ATHR_STATUS_LINK_PASS) {                linkCount++;            } else {                lostLinks++;                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n",                                               ethUnit, phyUnit));                lastStatus->isPhyAlive = FALSE;            }        } else { /* last known link status was DEAD */            /* Check for reset complete */            phy_reg_read(phyBase, phyAddr, ATHR_PHY_STATUS, &phyHwStatus);            if (!ATHR_RESET_DONE(phyHwStatus))                continue;            /* Check for AutoNegotiation complete */                        if (ATHR_AUTONEG_DONE(phyHwStatus)) {                //printk("autoneg done\n");                gainedLinks++;                linkCount++;                DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n",                                               ethUnit, phyUnit));                lastStatus->isPhyAlive = TRUE;            }        }    }    return (linkCount);#if 0    if (linkCount == 0) {        if (lostLinks) {            /* We just lost the last link for this MAC */            phyLinkLost(ethUnit);        }    } else {        if (gainedLinks == linkCount) {            /* We just gained our first link(s) for this MAC */            phyLinkGained(ethUnit);        }    }#endif}#ifdef CFG_ATHRHDR_ENvoid athr_hdr_timeout(void){	printf("%s\n",__func__);	eth_halt();        NetState = NETLOOP_FAIL; }void athr_hdr_handler(uchar *recv_pkt, unsigned dest, unsigned src, unsigned len){	header_receive_pkt(recv_pkt);	NetState = NETLOOP_SUCCESS;}static intathrs26_header_config_reg (struct eth_device *dev, uint8_t wr_flag,                           uint16_t reg_addr, uint16_t cmd_len,                           uint8_t *val){    at_header_t at_header;    reg_cmd_t reg_cmd;    uchar *AthrHdrPkt;    AthrHdrPkt = NetTxPacket;    if(AthrHdrPkt == NULL) {		printf("Null packet\n");		return;    }    memset(AthrHdrPkt,0,60);    /*fill at_header*/    at_header.reserved0 = 0x10;  //default    at_header.priority = 0;    at_header.type = 0x5;    at_header.broadcast = 0;    at_header.from_cpu = 1;    at_header.reserved1 = 0x01; //default    at_header.port_num = 0;    AthrHdrPkt[0] = at_header.port_num;    AthrHdrPkt[0] |= at_header.reserved1 << 4;    AthrHdrPkt[0] |= at_header.from_cpu << 6;    AthrHdrPkt[0] |= at_header.broadcast << 7;    AthrHdrPkt[1] = at_header.type;    AthrHdrPkt[1] |= at_header.priority << 4;    AthrHdrPkt[1] |= at_header.reserved0 << 6;    /*fill reg cmd*/    if(cmd_len > 4)        cmd_len = 4;//only support 32bits register r/w    reg_cmd.reg_addr = reg_addr&0x3FFFC;    reg_cmd.cmd_len = cmd_len;    reg_cmd.cmd = wr_flag;    reg_cmd.reserved2 = 0x5; //default    reg_cmd.seq_num = seqcnt;    AthrHdrPkt[2] = reg_cmd.reg_addr & 0xff;    AthrHdrPkt[3] = (reg_cmd.reg_addr & 0xff00) >> 8;    AthrHdrPkt[4] = (reg_cmd.reg_addr & 0x30000) >> 16;    AthrHdrPkt[4] |= reg_cmd.cmd_len << 4;    AthrHdrPkt[5] = reg_cmd.cmd << 4;    AthrHdrPkt[5] |= reg_cmd.reserved2 << 5;    AthrHdrPkt[6] = (reg_cmd.seq_num & 0x7f) << 1;    AthrHdrPkt[7] = (reg_cmd.seq_num & 0x7f80) >> 7;    AthrHdrPkt[8] = (reg_cmd.seq_num & 0x7f8000) >> 15;    AthrHdrPkt[9] = (reg_cmd.seq_num & 0x7f800000) >> 23;    /*fill reg data*/    if(!wr_flag)//write        memcpy((AthrHdrPkt + 10), val, cmd_len);        /*start xmit*/    if(dev == NULL) {	printf("ERROR device not found\n");	return -1;    }    header_xmit(dev, AthrHdrPkt ,60);    return 0;}void athr_hdr_func(void) {   NetSetTimeout (1 * CFG_HZ,athr_hdr_timeout );   NetSetHandler (athr_hdr_handler);   if(cmd)    	athrs26_header_config_reg(lan_mac, cmd, cmd_read.reg_addr, cmd_read.cmd_len, cmd_read.reg_data);   else         athrs26_header_config_reg(lan_mac, cmd, cmd_write.reg_addr, cmd_write.cmd_len, cmd_write.reg_data);}static intathrs26_header_write_reg(uint16_t reg_addr, uint16_t cmd_len, uint8_t *reg_data){    int i = 2;    cmd_write.reg_addr = reg_addr;    cmd_write.cmd_len = cmd_len;    cmd_write.reg_data = reg_data;    cmd = 0;    seqcnt++;    do {	if (NetLoop(ATHRHDR) >= 0) /* polls for read/write ack from PHY */	   break;    } while (i--);    return i;}static intathrs26_header_read_reg(uint16_t reg_addr, uint16_t cmd_len, uint8_t *reg_data){    int i = 2;    cmd_read.reg_addr = reg_addr;    cmd_read.cmd_len = cmd_len;    cmd_read.reg_data = reg_data;    cmd = 1;    seqcnt++;    do {        if (NetLoop(ATHRHDR) >= 0) /* polls for read/write ack from PHY */           break;    } while (i--);    if ((i==0) || (seqcnt != cmd_resp.seq) || (cmd_len != cmd_resp.len)) {        return -1;    }    memcpy (cmd_read.reg_data, cmd_resp.data, cmd_len);    return 0;}int header_receive_pkt(uchar *recv_pkt){    cmd_resp.len = recv_pkt[4] >> 4;    if (cmd_resp.len > 10)        goto out;    cmd_resp.seq = recv_pkt[6] >> 1;    cmd_resp.seq |= recv_pkt[7] << 7;    cmd_resp.seq |= recv_pkt[8] << 15;    cmd_resp.seq |= recv_pkt[9] << 23;    if (cmd_resp.seq < seqcnt)        goto out;    memcpy (cmd_resp.data, (recv_pkt + 10), cmd_resp.len);out:     return 0;}void athrs26_reg_dev(struct eth_device *mac){    lan_mac = mac;}#endifstatic uint32_tathrs26_reg_read(uint16_t reg_addr){#ifndef CFG_ATHRHDR_REG    uint16_t reg_word_addr = reg_addr / 2, phy_val;    uint32_t phy_addr;    uint8_t phy_reg;         /* configure register high address */    phy_addr = 0x18;    phy_reg = 0x0;    phy_val = (reg_word_addr >> 8) & 0x1ff;         /* bit16-8 of reg address*/    phy_reg_write (0, phy_addr, phy_reg, phy_val);    /* read register with low address */    phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */    phy_reg = reg_word_addr & 0x1f;                 /* bit 4-0 of reg address*/    phy_reg_read(0, phy_addr, phy_reg, &phy_val);        return phy_val;#else    uint8_t reg_data[4];    memset (reg_data, 0, 4);    athrs26_header_read_reg(reg_addr, 4, reg_data);    return (reg_data[0] | (reg_data[1] << 8) | (reg_data[2] << 16) | (reg_data[3] << 24));#endif}static voidathrs26_reg_write(uint16_t reg_addr, uint32_t reg_val){#ifndef CFG_ATHRHDR_REG    uint16_t reg_word_addr = reg_addr / 2, phy_val;    uint32_t phy_addr;    uint8_t phy_reg;     /* configure register high address */    phy_addr = 0x18;    phy_reg = 0x0;    phy_val = (reg_word_addr >> 8) & 0x1ff;         /* bit16-8 of reg address*/    phy_reg_write (0, phy_addr, phy_reg, phy_val);    /* read register with low address */    phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */    phy_reg = reg_word_addr & 0x1f;                 /* bit 4-0 of reg address */    phy_reg_write (0, phy_addr, phy_reg, reg_val);#else    uint8_t reg_data[4];    memset (reg_data, 0, 4);    reg_data[0] = (uint8_t)(0x00ff & reg_val);    reg_data[1] = (uint8_t)((0xff00 & reg_val) >> 8);    reg_data[2] = (uint8_t)((0xff0000 & reg_val) >> 16);    reg_data[3] = (uint8_t)((0xff000000 & reg_val) >> 24);    athrs26_header_write_reg (reg_addr, 4, reg_data);#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -