|
|
|
@ -49,9 +49,9 @@ |
|
|
|
|
struct mii_dev { |
|
|
|
|
struct list_head link; |
|
|
|
|
char *name; |
|
|
|
|
int (* read)(char *devname, unsigned char addr, |
|
|
|
|
int (*read) (char *devname, unsigned char addr, |
|
|
|
|
unsigned char reg, unsigned short *value); |
|
|
|
|
int (* write)(char *devname, unsigned char addr, |
|
|
|
|
int (*write) (char *devname, unsigned char addr, |
|
|
|
|
unsigned char reg, unsigned short value); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -62,9 +62,9 @@ static struct mii_dev *current_mii; |
|
|
|
|
* |
|
|
|
|
* Initialize global data. Need to be called before any other miiphy routine. |
|
|
|
|
*/ |
|
|
|
|
void miiphy_init() |
|
|
|
|
void miiphy_init () |
|
|
|
|
{ |
|
|
|
|
INIT_LIST_HEAD(&mii_devs); |
|
|
|
|
INIT_LIST_HEAD (&mii_devs); |
|
|
|
|
current_mii = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -72,10 +72,10 @@ void miiphy_init() |
|
|
|
|
* |
|
|
|
|
* Register read and write MII access routines for the device <name>. |
|
|
|
|
*/ |
|
|
|
|
void miiphy_register(char *name, |
|
|
|
|
int (* read)(char *devname, unsigned char addr, |
|
|
|
|
void miiphy_register (char *name, |
|
|
|
|
int (*read) (char *devname, unsigned char addr, |
|
|
|
|
unsigned char reg, unsigned short *value), |
|
|
|
|
int (* write)(char *devname, unsigned char addr, |
|
|
|
|
int (*write) (char *devname, unsigned char addr, |
|
|
|
|
unsigned char reg, unsigned short value)) |
|
|
|
|
{ |
|
|
|
|
struct list_head *entry; |
|
|
|
@ -84,63 +84,64 @@ void miiphy_register(char *name, |
|
|
|
|
unsigned int name_len; |
|
|
|
|
|
|
|
|
|
/* check if we have unique name */ |
|
|
|
|
list_for_each(entry, &mii_devs) { |
|
|
|
|
miidev = list_entry(entry, struct mii_dev, link); |
|
|
|
|
if (strcmp(miidev->name, name) == 0) { |
|
|
|
|
printf("miiphy_register: non unique device name '%s'\n", |
|
|
|
|
name); |
|
|
|
|
list_for_each (entry, &mii_devs) { |
|
|
|
|
miidev = list_entry (entry, struct mii_dev, link); |
|
|
|
|
if (strcmp (miidev->name, name) == 0) { |
|
|
|
|
printf ("miiphy_register: non unique device name " |
|
|
|
|
"'%s'\n", name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* allocate memory */ |
|
|
|
|
name_len = strlen(name); |
|
|
|
|
new_dev = (struct mii_dev *)malloc(sizeof(struct mii_dev) + name_len + 1); |
|
|
|
|
name_len = strlen (name); |
|
|
|
|
new_dev = |
|
|
|
|
(struct mii_dev *)malloc (sizeof (struct mii_dev) + name_len + 1); |
|
|
|
|
|
|
|
|
|
if(new_dev == NULL) { |
|
|
|
|
printf("miiphy_register: cannot allocate memory for '%s'\n", |
|
|
|
|
if (new_dev == NULL) { |
|
|
|
|
printf ("miiphy_register: cannot allocate memory for '%s'\n", |
|
|
|
|
name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
memset(new_dev, 0, sizeof(struct mii_dev) + name_len); |
|
|
|
|
memset (new_dev, 0, sizeof (struct mii_dev) + name_len); |
|
|
|
|
|
|
|
|
|
/* initalize mii_dev struct fields */ |
|
|
|
|
INIT_LIST_HEAD(&new_dev->link); |
|
|
|
|
INIT_LIST_HEAD (&new_dev->link); |
|
|
|
|
new_dev->read = read; |
|
|
|
|
new_dev->write = write; |
|
|
|
|
new_dev->name = (char *)(new_dev + 1); |
|
|
|
|
strncpy(new_dev->name, name, name_len); |
|
|
|
|
strncpy (new_dev->name, name, name_len); |
|
|
|
|
new_dev->name[name_len] = '\0'; |
|
|
|
|
|
|
|
|
|
debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", |
|
|
|
|
debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", |
|
|
|
|
new_dev->name, new_dev->read, new_dev->write); |
|
|
|
|
|
|
|
|
|
/* add it to the list */ |
|
|
|
|
list_add_tail(&new_dev->link, &mii_devs); |
|
|
|
|
list_add_tail (&new_dev->link, &mii_devs); |
|
|
|
|
|
|
|
|
|
if (!current_mii) |
|
|
|
|
current_mii = new_dev; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int miiphy_set_current_dev(char *devname) |
|
|
|
|
int miiphy_set_current_dev (char *devname) |
|
|
|
|
{ |
|
|
|
|
struct list_head *entry; |
|
|
|
|
struct mii_dev *dev; |
|
|
|
|
|
|
|
|
|
list_for_each(entry, &mii_devs) { |
|
|
|
|
dev = list_entry(entry, struct mii_dev, link); |
|
|
|
|
list_for_each (entry, &mii_devs) { |
|
|
|
|
dev = list_entry (entry, struct mii_dev, link); |
|
|
|
|
|
|
|
|
|
if (strcmp(devname, dev->name) == 0) { |
|
|
|
|
if (strcmp (devname, dev->name) == 0) { |
|
|
|
|
current_mii = dev; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printf("No such device: %s\n", devname); |
|
|
|
|
printf ("No such device: %s\n", devname); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char *miiphy_get_current_dev() |
|
|
|
|
char *miiphy_get_current_dev () |
|
|
|
|
{ |
|
|
|
|
if (current_mii) |
|
|
|
|
return current_mii->name; |
|
|
|
@ -156,7 +157,7 @@ char *miiphy_get_current_dev() |
|
|
|
|
* Returns: |
|
|
|
|
* 0 on success |
|
|
|
|
*/ |
|
|
|
|
int miiphy_read(char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
int miiphy_read (char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
unsigned short *value) |
|
|
|
|
{ |
|
|
|
|
struct list_head *entry; |
|
|
|
@ -165,22 +166,22 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
int read_ret = 0; |
|
|
|
|
|
|
|
|
|
if (!devname) { |
|
|
|
|
printf("NULL device name!\n"); |
|
|
|
|
printf ("NULL device name!\n"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
list_for_each(entry, &mii_devs) { |
|
|
|
|
dev = list_entry(entry, struct mii_dev, link); |
|
|
|
|
list_for_each (entry, &mii_devs) { |
|
|
|
|
dev = list_entry (entry, struct mii_dev, link); |
|
|
|
|
|
|
|
|
|
if (strcmp(devname, dev->name) == 0) { |
|
|
|
|
if (strcmp (devname, dev->name) == 0) { |
|
|
|
|
found_dev = 1; |
|
|
|
|
read_ret = dev->read(devname, addr, reg, value); |
|
|
|
|
read_ret = dev->read (devname, addr, reg, value); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (found_dev == 0) |
|
|
|
|
printf("No such device: %s\n", devname); |
|
|
|
|
printf ("No such device: %s\n", devname); |
|
|
|
|
|
|
|
|
|
return ((found_dev) ? read_ret : 1); |
|
|
|
|
} |
|
|
|
@ -193,7 +194,7 @@ int miiphy_read(char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
* Returns: |
|
|
|
|
* 0 on success |
|
|
|
|
*/ |
|
|
|
|
int miiphy_write(char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
int miiphy_write (char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
unsigned short value) |
|
|
|
|
{ |
|
|
|
|
struct list_head *entry; |
|
|
|
@ -202,22 +203,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
int write_ret = 0; |
|
|
|
|
|
|
|
|
|
if (!devname) { |
|
|
|
|
printf("NULL device name!\n"); |
|
|
|
|
printf ("NULL device name!\n"); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
list_for_each(entry, &mii_devs) { |
|
|
|
|
dev = list_entry(entry, struct mii_dev, link); |
|
|
|
|
list_for_each (entry, &mii_devs) { |
|
|
|
|
dev = list_entry (entry, struct mii_dev, link); |
|
|
|
|
|
|
|
|
|
if (strcmp(devname, dev->name) == 0) { |
|
|
|
|
if (strcmp (devname, dev->name) == 0) { |
|
|
|
|
found_dev = 1; |
|
|
|
|
write_ret = dev->write(devname, addr, reg, value); |
|
|
|
|
write_ret = dev->write (devname, addr, reg, value); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (found_dev == 0) |
|
|
|
|
printf("No such device: %s\n", devname); |
|
|
|
|
printf ("No such device: %s\n", devname); |
|
|
|
|
|
|
|
|
|
return ((found_dev) ? write_ret : 1); |
|
|
|
|
} |
|
|
|
@ -226,23 +227,22 @@ int miiphy_write(char *devname, unsigned char addr, unsigned char reg, |
|
|
|
|
* |
|
|
|
|
* Print out list of registered MII capable devices. |
|
|
|
|
*/ |
|
|
|
|
void miiphy_listdev(void) |
|
|
|
|
void miiphy_listdev (void) |
|
|
|
|
{ |
|
|
|
|
struct list_head *entry; |
|
|
|
|
struct mii_dev *dev; |
|
|
|
|
|
|
|
|
|
puts("MII devices: "); |
|
|
|
|
list_for_each(entry, &mii_devs) { |
|
|
|
|
dev = list_entry(entry, struct mii_dev, link); |
|
|
|
|
printf("'%s' ", dev->name); |
|
|
|
|
puts ("MII devices: "); |
|
|
|
|
list_for_each (entry, &mii_devs) { |
|
|
|
|
dev = list_entry (entry, struct mii_dev, link); |
|
|
|
|
printf ("'%s' ", dev->name); |
|
|
|
|
} |
|
|
|
|
puts("\n"); |
|
|
|
|
puts ("\n"); |
|
|
|
|
|
|
|
|
|
if (current_mii) |
|
|
|
|
printf("Current device: '%s'\n", current_mii->name); |
|
|
|
|
printf ("Current device: '%s'\n", current_mii->name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* |
|
|
|
|
* Read the OUI, manufacture's model number, and revision number. |
|
|
|
@ -254,9 +254,7 @@ void miiphy_listdev(void) |
|
|
|
|
* Returns: |
|
|
|
|
* 0 on success |
|
|
|
|
*/ |
|
|
|
|
int miiphy_info (char *devname, |
|
|
|
|
unsigned char addr, |
|
|
|
|
unsigned int *oui, |
|
|
|
|
int miiphy_info (char *devname, unsigned char addr, unsigned int *oui, |
|
|
|
|
unsigned char *model, unsigned char *rev) |
|
|
|
|
{ |
|
|
|
|
unsigned int reg = 0; |
|
|
|
@ -288,13 +286,12 @@ int miiphy_info (char *devname, |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg); |
|
|
|
|
#endif |
|
|
|
|
*oui = ( reg >> 10); |
|
|
|
|
*model = (unsigned char) ((reg >> 4) & 0x0000003F); |
|
|
|
|
*rev = (unsigned char) ( reg & 0x0000000F); |
|
|
|
|
*oui = (reg >> 10); |
|
|
|
|
*model = (unsigned char)((reg >> 4) & 0x0000003F); |
|
|
|
|
*rev = (unsigned char)(reg & 0x0000000F); |
|
|
|
|
return (0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* |
|
|
|
|
* Reset the PHY. |
|
|
|
@ -345,7 +342,6 @@ int miiphy_reset (char *devname, unsigned char addr) |
|
|
|
|
return (0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* |
|
|
|
|
* Determine the ethernet speed (10/100). |
|
|
|
@ -359,7 +355,8 @@ int miiphy_speed (char *devname, unsigned char addr) |
|
|
|
|
printf ("PHY 1000BT Status read failed\n"); |
|
|
|
|
} else { |
|
|
|
|
if (reg != 0xFFFF) { |
|
|
|
|
if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) !=0) { |
|
|
|
|
if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) |
|
|
|
|
!= 0) { |
|
|
|
|
return (_1000BASET); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -393,7 +390,6 @@ int miiphy_speed (char *devname, unsigned char addr) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* |
|
|
|
|
* Determine full/half duplex. |
|
|
|
@ -406,9 +402,9 @@ int miiphy_duplex (char *devname, unsigned char addr) |
|
|
|
|
if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { |
|
|
|
|
printf ("PHY 1000BT Status read failed\n"); |
|
|
|
|
} else { |
|
|
|
|
if ( (reg != 0xFFFF) && |
|
|
|
|
(reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) ) { |
|
|
|
|
if ((reg & PHY_1000BTSR_1000FD) !=0) { |
|
|
|
|
if ((reg != 0xFFFF) && |
|
|
|
|
(reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) { |
|
|
|
|
if ((reg & PHY_1000BTSR_1000FD) != 0) { |
|
|
|
|
return (FULL); |
|
|
|
|
} else { |
|
|
|
|
return (HALF); |
|
|
|
@ -455,7 +451,7 @@ int miiphy_link (char *devname, unsigned char addr) |
|
|
|
|
unsigned short reg; |
|
|
|
|
|
|
|
|
|
/* dummy read; needed to latch some phys */ |
|
|
|
|
(void)miiphy_read(devname, addr, PHY_BMSR, ®); |
|
|
|
|
(void)miiphy_read (devname, addr, PHY_BMSR, ®); |
|
|
|
|
if (miiphy_read (devname, addr, PHY_BMSR, ®)) { |
|
|
|
|
puts ("PHY_BMSR read failed, assuming no link\n"); |
|
|
|
|
return (0); |
|
|
|
@ -469,5 +465,4 @@ int miiphy_link (char *devname, unsigned char addr) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#endif /* CONFIG_MII */ |
|
|
|
|