Files
mips/src/marvell_88e1111.c
T
jens 26291bca3d - initial import
git-svn-id: http://moon:8086/svn/mips@1 a8ebac50-d88d-4704-bea3-6648445a41b3
2014-07-20 15:01:37 +00:00

195 lines
5.4 KiB
C

/** *******************************************************************************
*
* Project: Robotics library for the Autonomous Robotics Development Platform
* Port by: Jorge Sánchez de Nova jssdn (mail)_(at) kth.se
*
* NOTE: This code is based on the Xilinx XAPP1042.
*
* Description:
* Routines to control and display the status of a Marvell 88E1111 Ethernet PHY.
*
* Xilinx disclaimer below apply.
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* (c) Copyright 2008 Xilinx, Inc.
* All rights reserved.
*
******************************************************************************* **/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include "libsys.h"
//#include "errno.h"
#include "marvell_88e1111.h"
/*
* Pointers to functions which will read/write the PHY registers.
* These must be set with marvell_phy_setvectors() before any other functions
* in this file are called.
*/
static PhyWrite_t *PhyWrite_fp;
static PhyRead_t *PhyRead_fp;
/*
* marvell_phy_setvectors:
* initialize read/write vectors to the driver which will provide access
* to the PHY registers.
*/
void marvell_phy_setvectors (PhyRead_t *read_fp, PhyWrite_t *write_fp)
{
PhyWrite_fp = write_fp;
PhyRead_fp = read_fp;
}
/*
* marvell_phy_detected:
* Returns 0 if Marvell PHY detected at PhyAddress, otherwise returns
* -1.
*/
int marvell_phy_detected (void *phy_inst, uint32_t PhyAddress)
{
uint16_t val;
if (PhyRead_fp == NULL) {
printf("ERROR: PHY accessor vectors not set.\n");
return -1;
}
(*PhyRead_fp)(phy_inst, PhyAddress, MPHY_ID0_REG, &val);
if (val == MPHY_ID0_MARVELL_OUI) {
return 0;
}
return -1;
}
/*
* marvell_phy_set_1000mb_autoneg:
* Enable or disable the autonegotiation of 1000MB
*/
void marvell_phy_set_1000mb_autoneg (void *phy_inst, uint32_t PhyAddress, int Enable)
{
uint16_t val;
if ((PhyRead_fp == NULL) || (PhyWrite_fp == NULL)) {
printf("ERROR: PHY accessor vectors not set.\n\r");
return;
}
/*
* Change advertised capabilities
*/
(*PhyRead_fp)(phy_inst, PhyAddress, MPHY_1000BT_CONTROL_REG, &val);
if (Enable) {
val |= (MPHY_1000BT_CONTROL_ADV_1000BT_FD |
MPHY_1000BT_CONTROL_ADV_1000BT_HD);
} else {
val &= ~(MPHY_1000BT_CONTROL_ADV_1000BT_FD |
MPHY_1000BT_CONTROL_ADV_1000BT_HD);
}
(*PhyWrite_fp)(phy_inst, PhyAddress, MPHY_1000BT_CONTROL_REG, val);
/*
* Re-negotiate
*/
(*PhyRead_fp)(phy_inst, PhyAddress, MPHY_CONTROL_REG, &val);
val |= MPHY_CONTROL_RSTRT_AUTONEG;
(*PhyWrite_fp)(phy_inst, PhyAddress, MPHY_CONTROL_REG, val);
}
/*
* marvell_phy_link_status:
* Returns 0 if LINK is UP
* Returns -1 if LINK is DOWN
*/
int marvell_phy_link_status (void *phy_inst, uint32_t PhyAddress)
{
uint16_t val;
if (PhyRead_fp == NULL) {
printf("ERROR: PHY accessor vectors not set.\n\r");
return -1;
}
(*PhyRead_fp)(phy_inst, PhyAddress, MPHY_SPCFC_STATUS_REG, &val);
// printf("MPHY_SPCFC_STATUS_REG = %08X\n", val);
if (val & MPHY_SPCFC_STAT_LINK_RT) {
return 0;
}
return -1;
}
/*
* marvell_phy_display_status:
*/
void marvell_phy_display_status (void *phy_inst, uint32_t PhyAddress)
{
uint16_t val, speed_status;
if (PhyRead_fp == NULL) {
printf("ERROR: PHY accessor vectors not set.\n\r");
return;
}
(*PhyRead_fp)(phy_inst, PhyAddress, MPHY_SPCFC_STATUS_REG, &val);
if (val & MPHY_SPCFC_STAT_LINK_RT) {
printf("PHY Status: LINK_OK ");
} else {
printf("PHY Status: LINK_DOWN\n\r");
return;
}
speed_status = val >> MPHY_SPCFC_STAT_SPD_SHIFT;
switch (speed_status) {
case MPHY_SPCFC_STAT_SPD_RESVD:
printf("SPEED-RESERVED ");
break;
case MPHY_SPCFC_STAT_SPD_1000:
printf("SPEED-1000MB ");
break;
case MPHY_SPCFC_STAT_SPD_100:
printf("SPEED-100MB ");
break;
case MPHY_SPCFC_STAT_SPD_10:
printf("SPEED-10MB ");
break;
}
if (val & MPHY_SPCFC_STAT_DUPLEX) {
printf("FULL-DUPLEX ");
} else {
printf("HALF-DUPLEX ");
}
if (val & MPHY_SPCFC_STAT_SPD_DUP_RSLVD) {
printf("SPD_DPLX_RSLVD ");
} else {
printf("SPD_DPLX_NOT_RSLVD ");
}
if (val & MPHY_SPCFC_STAT_MDIX) {
printf("MDIX ");
} else {
printf("MDI ");
}
printf("\n");
}