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

📄 uec_phy.c

📁 from wangkj@yahoo.com 电路原理图和详细说明: amd.9966.org或者 arm.9966.org 都是原创,包括boot, loader,u-boot,linu
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2005 Freescale Semiconductor, Inc. * * Author: Shlomi Gridish * * Description: UCC GETH Driver -- PHY handling *		Driver for UEC on QE *		Based on 8260_io/fcc_enet.c * * This program is free software; you can redistribute	it and/or modify it * under  the terms of	the GNU General	 Public License as published by the * Free Software Foundation;  either version 2 of the  License, or (at your * option) any later version. * */#include "common.h"#include "net.h"#include "malloc.h"#include "asm/errno.h"#include "asm/immap_qe.h"#include "asm/io.h"#include "qe.h"#include "uccf.h"#include "uec.h"#include "uec_phy.h"#include "miiphy.h"#if defined(CONFIG_QE)#define UEC_VERBOSE_DEBUG#define ugphy_printk(format, arg...)  \	printf(format "\n", ## arg)#define ugphy_dbg(format, arg...)	     \	ugphy_printk(format , ## arg)#define ugphy_err(format, arg...)	     \	ugphy_printk(format , ## arg)#define ugphy_info(format, arg...)	     \	ugphy_printk(format , ## arg)#define ugphy_warn(format, arg...)	     \	ugphy_printk(format , ## arg)#ifdef UEC_VERBOSE_DEBUG#define ugphy_vdbg ugphy_dbg#else#define ugphy_vdbg(ugeth, fmt, args...) do { } while (0)#endif /* UEC_VERBOSE_DEBUG */static void config_genmii_advert (struct uec_mii_info *mii_info);static void genmii_setup_forced (struct uec_mii_info *mii_info);static void genmii_restart_aneg (struct uec_mii_info *mii_info);static int gbit_config_aneg (struct uec_mii_info *mii_info);static int genmii_config_aneg (struct uec_mii_info *mii_info);static int genmii_update_link (struct uec_mii_info *mii_info);static int genmii_read_status (struct uec_mii_info *mii_info);u16 phy_read (struct uec_mii_info *mii_info, u16 regnum);void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val);/* Write value to the PHY for this device to the register at regnum, *//* waiting until the write is done before it returns.  All PHY *//* configuration has to be done through the TSEC1 MIIM regs */void write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value){	uec_private_t *ugeth = (uec_private_t *) dev->priv;	uec_t *ug_regs;	enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;	u32 tmp_reg;	ug_regs = ugeth->uec_regs;	/* Stop the MII management read cycle */	out_be32 (&ug_regs->miimcom, 0);	/* Setting up the MII Mangement Address Register */	tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;	out_be32 (&ug_regs->miimadd, tmp_reg);	/* Setting up the MII Mangement Control Register with the value */	out_be32 (&ug_regs->miimcon, (u32) value);	/* Wait till MII management write is complete */	while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY);	udelay (100000);}/* Reads from register regnum in the PHY for device dev, *//* returning the value.  Clears miimcom first.  All PHY *//* configuration has to be done through the TSEC1 MIIM regs */int read_phy_reg (struct eth_device *dev, int mii_id, int regnum){	uec_private_t *ugeth = (uec_private_t *) dev->priv;	uec_t *ug_regs;	enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;	u32 tmp_reg;	u16 value;	ug_regs = ugeth->uec_regs;	/* Setting up the MII Mangement Address Register */	tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;	out_be32 (&ug_regs->miimadd, tmp_reg);	/* Perform an MII management read cycle */	out_be32 (&ug_regs->miimcom, 0);	out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE);	/* Wait till MII management write is complete */	while ((in_be32 (&ug_regs->miimind)) &	       (MIIMIND_NOT_VALID | MIIMIND_BUSY));	udelay (100000);	/* Read MII management status  */	value = (u16) in_be32 (&ug_regs->miimstat);	if (value == 0xffff)		ugphy_warn			("read wrong value : mii_id %d,mii_reg %d, base %08x",			 mii_id, mii_reg, (u32) & (ug_regs->miimcfg));	return (value);}void mii_clear_phy_interrupt (struct uec_mii_info *mii_info){	if (mii_info->phyinfo->ack_interrupt)		mii_info->phyinfo->ack_interrupt (mii_info);}void mii_configure_phy_interrupt (struct uec_mii_info *mii_info,				  u32 interrupts){	mii_info->interrupts = interrupts;	if (mii_info->phyinfo->config_intr)		mii_info->phyinfo->config_intr (mii_info);}/* Writes MII_ADVERTISE with the appropriate values, after * sanitizing advertise to make sure only supported features * are advertised */static void config_genmii_advert (struct uec_mii_info *mii_info){	u32 advertise;	u16 adv;	/* Only allow advertising what this PHY supports */	mii_info->advertising &= mii_info->phyinfo->features;	advertise = mii_info->advertising;	/* Setup standard advertisement */	adv = phy_read (mii_info, PHY_ANAR);	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);	if (advertise & ADVERTISED_10baseT_Half)		adv |= ADVERTISE_10HALF;	if (advertise & ADVERTISED_10baseT_Full)		adv |= ADVERTISE_10FULL;	if (advertise & ADVERTISED_100baseT_Half)		adv |= ADVERTISE_100HALF;	if (advertise & ADVERTISED_100baseT_Full)		adv |= ADVERTISE_100FULL;	phy_write (mii_info, PHY_ANAR, adv);}static void genmii_setup_forced (struct uec_mii_info *mii_info){	u16 ctrl;	u32 features = mii_info->phyinfo->features;	ctrl = phy_read (mii_info, PHY_BMCR);	ctrl &= ~(PHY_BMCR_DPLX | PHY_BMCR_100_MBPS |		  PHY_BMCR_1000_MBPS | PHY_BMCR_AUTON);	ctrl |= PHY_BMCR_RESET;	switch (mii_info->speed) {	case SPEED_1000:		if (features & (SUPPORTED_1000baseT_Half				| SUPPORTED_1000baseT_Full)) {			ctrl |= PHY_BMCR_1000_MBPS;			break;		}		mii_info->speed = SPEED_100;	case SPEED_100:		if (features & (SUPPORTED_100baseT_Half				| SUPPORTED_100baseT_Full)) {			ctrl |= PHY_BMCR_100_MBPS;			break;		}		mii_info->speed = SPEED_10;	case SPEED_10:		if (features & (SUPPORTED_10baseT_Half				| SUPPORTED_10baseT_Full))			break;	default:		/* Unsupported speed! */		ugphy_err ("%s: Bad speed!", mii_info->dev->name);		break;	}	phy_write (mii_info, PHY_BMCR, ctrl);}/* Enable and Restart Autonegotiation */static void genmii_restart_aneg (struct uec_mii_info *mii_info){	u16 ctl;	ctl = phy_read (mii_info, PHY_BMCR);	ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);	phy_write (mii_info, PHY_BMCR, ctl);}static int gbit_config_aneg (struct uec_mii_info *mii_info){	u16 adv;	u32 advertise;	if (mii_info->autoneg) {		/* Configure the ADVERTISE register */		config_genmii_advert (mii_info);		advertise = mii_info->advertising;		adv = phy_read (mii_info, MII_1000BASETCONTROL);		adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |			 MII_1000BASETCONTROL_HALFDUPLEXCAP);		if (advertise & SUPPORTED_1000baseT_Half)			adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;		if (advertise & SUPPORTED_1000baseT_Full)			adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;		phy_write (mii_info, MII_1000BASETCONTROL, adv);		/* Start/Restart aneg */		genmii_restart_aneg (mii_info);	} else		genmii_setup_forced (mii_info);	return 0;}static int marvell_config_aneg (struct uec_mii_info *mii_info){	/* The Marvell PHY has an errata which requires	 * that certain registers get written in order	 * to restart autonegotiation */	phy_write (mii_info, PHY_BMCR, PHY_BMCR_RESET);	phy_write (mii_info, 0x1d, 0x1f);	phy_write (mii_info, 0x1e, 0x200c);	phy_write (mii_info, 0x1d, 0x5);	phy_write (mii_info, 0x1e, 0);	phy_write (mii_info, 0x1e, 0x100);	gbit_config_aneg (mii_info);	return 0;}static int genmii_config_aneg (struct uec_mii_info *mii_info){	if (mii_info->autoneg) {		config_genmii_advert (mii_info);		genmii_restart_aneg (mii_info);	} else		genmii_setup_forced (mii_info);	return 0;}static int genmii_update_link (struct uec_mii_info *mii_info){	u16 status;	/* Do a fake read */	phy_read (mii_info, PHY_BMSR);	/* Read link and autonegotiation status */	status = phy_read (mii_info, PHY_BMSR);	if ((status & PHY_BMSR_LS) == 0)		mii_info->link = 0;	else		mii_info->link = 1;	/* If we are autonegotiating, and not done,	 * return an error */	if (mii_info->autoneg && !(status & PHY_BMSR_AUTN_COMP))		return -EAGAIN;	return 0;}static int genmii_read_status (struct uec_mii_info *mii_info){	u16 status;	int err;	/* Update the link, but return if there	 * was an error */	err = genmii_update_link (mii_info);	if (err)		return err;	if (mii_info->autoneg) {		status = phy_read (mii_info, PHY_ANLPAR);

⌨️ 快捷键说明

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