📄 athrf1_phy.c
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. *//* * Manage the atheros ethernet PHY. * * All definitions in this file are operating system independent! */#ifdef __BDI#include "bdi.h"#else#ifdef __ECOS#if defined(CYGNUM_USE_ENET_VERBOSE)# undef VERBOSE# define VERBOSE CYGNUM_USE_ENET_VERBOSE#else# define VERBOSE 0#endif #define printk DEBUG_PRINTF#define udelay A_UDELAY#define mdelay(_x) udelay((_x)*1000)#else#include <linux/kernel.h>#include <asm/delay.h>#include "ar7100.h"#endif#endif#ifndef VERBOSE#define VERBOSE 0#endif#if 0#include <linux/kernel.h>#include <linux/config.h>#include <linux/types.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/delay.h>#endif#include "ag7100.h"#include "ag7100_phy.h"#define MODULE_NAME "ATHRF1"typedef struct { int is_enet_port; int mac_unit; unsigned int phy_addr;}athr_phy_t;athr_phy_t phy_info[] = { {is_enet_port: 1, mac_unit : 0, phy_addr : 0x00}};static athr_phy_t *athr_phy_find(int unit){ int i; athr_phy_t *phy; for(i = 0; i < sizeof(phy_info)/sizeof(athr_phy_t); i++) { phy = &phy_info[i]; if (phy->is_enet_port && (phy->mac_unit == unit)) return phy; } return NULL;}intathr_phy_setup(int unit){ athr_phy_t *phy = athr_phy_find(unit); uint16_t phyHwStatus; uint16_t timeout; if (!phy) { printk(MODULE_NAME": \nNo phy found for unit %d\n", unit); return; } /* * After the phy is reset, it takes a little while before * it can respond properly. */ phy_reg_write(unit, phy->phy_addr, ATHR_AUTONEG_ADVERT, ATHR_ADVERTISE_ALL); phy_reg_write(unit, phy->phy_addr, ATHR_1000BASET_CONTROL, ATHR_ADVERTISE_1000FULL); /* delay tx_clk */ phy_reg_write(unit, phy->phy_addr, 0x1D, 0x5); phy_reg_write(unit, phy->phy_addr, 0x1E, 0x100); /* Reset PHYs*/ phy_reg_write(unit, phy->phy_addr, ATHR_PHY_CONTROL, ATHR_CTRL_AUTONEGOTIATION_ENABLE | ATHR_CTRL_SOFTWARE_RESET); mdelay(500); /* * Wait up to 3 seconds for ALL associated PHYs to finish * autonegotiation. The only way we get out of here sooner is * if ALL PHYs are connected AND finish autonegotiation. */ timeout=20; for (;;) { phyHwStatus = phy_reg_read(unit, phy->phy_addr, ATHR_PHY_CONTROL); if (ATHR_RESET_DONE(phyHwStatus)) { printk(MODULE_NAME": Port %d, Neg Success\n", unit); break; } if (timeout == 0) { printk(MODULE_NAME": Port %d, Negogiation timeout\n", unit); break; } if (--timeout == 0) { printk(MODULE_NAME": Port %d, Negogiation timeout\n", unit); break; } mdelay(150); } printk(MODULE_NAME": unit %d phy addr %x ", unit, phy->phy_addr); printk(MODULE_NAME": reg0 %x\n", ag7100_mii_read(0, phy->phy_addr, 0));}intathr_phy_is_up(int unit){ int status; athr_phy_t *phy = athr_phy_find(unit); if (!phy) return 0; status = ag7100_mii_read(0, phy->phy_addr, ATHR_PHY_SPEC_STATUS); if (status & ATHR_STATUS_LINK_PASS) return 1; return 0;}intathr_phy_is_fdx(int unit){ int status; athr_phy_t *phy = athr_phy_find(unit); int ii = 200; if (!phy) return 0; do { status = ag7100_mii_read(0, phy->phy_addr, ATHR_PHY_SPEC_STATUS); mdelay(10); } while((!(status & ATHR_STATUS_RESOVLED)) && --ii); status = !(!(status & ATHER_STATUS_FULL_DEPLEX)); return (status);}intathr_phy_speed(int unit){ int status; athr_phy_t *phy = athr_phy_find(unit); int ii = 200; if (!phy) return 0; do { status = ag7100_mii_read(0, phy->phy_addr, ATHR_PHY_SPEC_STATUS); mdelay(10); }while((!(status & ATHR_STATUS_RESOVLED)) && --ii); status = ((status & ATHER_STATUS_LINK_MASK) >> ATHER_STATUS_LINK_SHIFT); switch(status) { case 0: return AG7100_PHY_SPEED_10T; case 1: return AG7100_PHY_SPEED_100TX; case 2: return AG7100_PHY_SPEED_1000T; default: printk(MODULE_NAME": Unkown speed read!\n"); } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -