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

📄 miiphy.c

📁 嵌入式ARM的一些源代码
💻 C
字号:
/*-----------------------------------------------------------------------------+
  |
  |       This source code has been made available to you by IBM on an AS-IS
  |       basis.  Anyone receiving this source is licensed under IBM
  |       copyrights to use it in any way he or she deems fit, including
  |       copying it, modifying it, compiling it, and redistributing it either
  |       with or without modifications.  No license under IBM patents or
  |       patent applications is to be implied by the copyright license.
  |
  |       Any user of this software should understand that IBM cannot provide
  |       technical support for this software and will not be responsible for
  |       any consequences resulting from the use of this software.
  |
  |       Any person who transfers this source code or any derivative work
  |       must include the IBM copyright notice, this paragraph, and the
  |       preceding two paragraphs in the transferred software.
  |
  |       COPYRIGHT   I B M   CORPORATION 1995
  |       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
  +-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------+
  |
  |  File Name:  miiphy.c
  |
  |  Function:   This module has utilities for accessing the MII PHY through 
  |	       the EMAC3 macro.
  |
  |  Author:     Mark Wisner
  |
  |  Change Activity-
  |
  |  Date        Description of Change                                       BY
  |  ---------   ---------------------                                       ---
  |  05-May-99   Created                                                     MKW
  |  01-Jul-99   Changed clock setting of sta_reg from 66Mhz to 50Mhz to 
  |              better match OPB speed. Also modified delay times.      	   JWB
  |  29-Jul-99   Added Full duplex support                                   MKW
  |  24-Aug-99   Removed printf from dp83843_duplex()                      JWB
  |  19-Jul-00   Ported to esd cpci405                                       sr
  |
  +-----------------------------------------------------------------------------*/

#include <ppcboot.h>
#include <asm/processor.h>
#include <ppc_asm.tmpl>
#include <commproc.h>
#include <405gp_enet.h>
#include <405_mal.h>
#include <miiphy.h>

#ifdef CONFIG_PPC405GP


/***********************************************************/
/* Dump out to the screen PHY regs                         */
/***********************************************************/

void miiphy_dump(void)
{
  unsigned long i;
  unsigned short data;

 
  for(i=0; i<0x1A; i++)
    { 
      if(miiphy_read(i, &data))
        {
          printf("read error for reg %lx\n\r",i);
          return;
        }  
      printf("Phy reg %lx ==> %4x\n\r", i, data); 
    
      /* jump to the next set of regs */
      if(i==0x07)
        i=0x0f;    
  
    } /* end for loop */
}   /* end dump */



/***********************************************************/
/* read a phy reg and return the value with a rc           */
/***********************************************************/

int miiphy_read(unsigned char reg, unsigned short * value)
{
  unsigned long sta_reg; /* STA scratch area */
  unsigned long i;
 
  /* see if it is ready for 1000 nsec */
  i=0;

  /* see if it is ready for  sec */
  while((in32(EMAC_STACR) & EMAC_STACR_OC) == 0)
    {
      udelay(7);
      if(i > 5)
        { printf("read err 1\n\r");
        return -1;
        }
      i++;
    }       
  sta_reg = reg;                        /* reg address */
  /* set clock (50Mhz) and read flags */
  sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ; 
  sta_reg = sta_reg | (PHY_ADDR << 5);  /* Phy address */
     
  out32(EMAC_STACR, sta_reg);
#if 0  /* test-only */
  printf("a2: write: EMAC_STACR=0x%0x\n", sta_reg); /* test-only */
#endif

  sta_reg = in32(EMAC_STACR);
  i=0;
  while(( sta_reg & EMAC_STACR_OC) == 0)
    {
      udelay(7);
      if(i > 5)
        { printf("read err 2\n\r");
        return -1;
        }
      i++;
      sta_reg = in32(EMAC_STACR);
    }
  if ((sta_reg & EMAC_STACR_PHYE) !=0)
    { printf("read err 3\n\r");
    printf("a2: read: EMAC_STACR=0x%0lx, i=%d\n", sta_reg, (int)i); /* test-only */
    return -1;
    }

  *value = *(short *)(&sta_reg);
  return 0;  
    
    
} /* phy_read */
 

/***********************************************************/
/* write a phy reg and return the value with a rc           */
/***********************************************************/

int miiphy_write(unsigned char reg, unsigned short value)
{
  unsigned long sta_reg; /* STA scratch area */
  unsigned long i;
 
  /* see if it is ready for 1000 nsec */
  i=0;

  while((in32(EMAC_STACR) & EMAC_STACR_OC) == 0)
    { 
      if(i>5)
        return -1;
      udelay(7);
      i++; 
    } 
  sta_reg=0;      
  sta_reg = reg;                        /* reg address */
  /* set clock (50Mhz) and read flags */
  sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
  sta_reg = sta_reg | ((unsigned long)PHY_ADDR << 5);  /* Phy address */
  memcpy(&sta_reg, &value,2);         /* put in data */
     
  out32(EMAC_STACR, sta_reg);

  /* wait for completion */
  i=0;     
  sta_reg = in32(EMAC_STACR);
  while(( sta_reg & EMAC_STACR_OC) == 0)
    {
      udelay(7);
      if(i > 5)
        return -1;
      i++;
      sta_reg = in32(EMAC_STACR);
    }

  if ((sta_reg & EMAC_STACR_PHYE) !=0)
    return -1;
  return 0;  
   
} /* phy_read */

/***********************************************************/
/* routine to read phy and determine the interface speed   */
/***********************************************************/
int miiphy_speed()
{
  int speed = _10BASET;          /* Assume 10Mbs */
  unsigned short bmcr = 0x0;

  if (miiphy_read(PHY_ANLPAR,&bmcr)) {
    printf("phy speed1 read failed \n\r");
    miiphy_dump();
  }

  if ((bmcr & PHY_ANLPAR_100) != 0) {
    speed = _100BASET;
  }

  return (speed);
}
/***********************************************************/
/* routine to read phy and determine the duplex mode       */
/***********************************************************/
int miiphy_duplex()
{
  int speed = HALF;          /* Assume HALF */
  unsigned short bmcr = 0x0;

  if (miiphy_read(PHY_ANLPAR,&bmcr)) 
    {
      printf("phy duplex read failed \n\r");
      miiphy_dump();
    }

  if ((bmcr & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) 
    speed = FULL;
  
  return (speed);
}

#endif /* CONFIG_PPC405GP */

⌨️ 快捷键说明

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