|
@@ -46,21 +46,45 @@
|
|
|
|
|
|
struct mii_dev {
|
|
|
struct list_head link;
|
|
|
- char *name;
|
|
|
- int (*read) (char *devname, unsigned char addr,
|
|
|
+ const char *name;
|
|
|
+ int (*read) (const char *devname, unsigned char addr,
|
|
|
unsigned char reg, unsigned short *value);
|
|
|
- int (*write) (char *devname, unsigned char addr,
|
|
|
+ int (*write) (const char *devname, unsigned char addr,
|
|
|
unsigned char reg, unsigned short value);
|
|
|
};
|
|
|
|
|
|
static struct list_head mii_devs;
|
|
|
static struct mii_dev *current_mii;
|
|
|
|
|
|
+/*
|
|
|
+ * Lookup the mii_dev struct by the registered device name.
|
|
|
+ */
|
|
|
+static struct mii_dev *miiphy_get_dev_by_name(const char *devname, int quiet)
|
|
|
+{
|
|
|
+ struct list_head *entry;
|
|
|
+ struct mii_dev *dev;
|
|
|
+
|
|
|
+ if (!devname) {
|
|
|
+ printf("NULL device name!\n");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ list_for_each(entry, &mii_devs) {
|
|
|
+ dev = list_entry(entry, struct mii_dev, link);
|
|
|
+ if (strcmp(dev->name, devname) == 0)
|
|
|
+ return dev;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!quiet)
|
|
|
+ printf("No such device: %s\n", devname);
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
/*****************************************************************************
|
|
|
*
|
|
|
* Initialize global data. Need to be called before any other miiphy routine.
|
|
|
*/
|
|
|
-void miiphy_init ()
|
|
|
+void miiphy_init(void)
|
|
|
{
|
|
|
INIT_LIST_HEAD (&mii_devs);
|
|
|
current_mii = NULL;
|
|
@@ -70,25 +94,21 @@ 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(const char *name,
|
|
|
+ int (*read) (const char *devname, unsigned char addr,
|
|
|
unsigned char reg, unsigned short *value),
|
|
|
- int (*write) (char *devname, unsigned char addr,
|
|
|
+ int (*write) (const char *devname, unsigned char addr,
|
|
|
unsigned char reg, unsigned short value))
|
|
|
{
|
|
|
- struct list_head *entry;
|
|
|
struct mii_dev *new_dev;
|
|
|
- struct mii_dev *miidev;
|
|
|
unsigned int name_len;
|
|
|
+ char *new_name;
|
|
|
|
|
|
/* 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);
|
|
|
- return;
|
|
|
- }
|
|
|
+ new_dev = miiphy_get_dev_by_name(name, 1);
|
|
|
+ if (new_dev) {
|
|
|
+ printf("miiphy_register: non unique device name '%s'\n", name);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
/* allocate memory */
|
|
@@ -107,9 +127,9 @@ void miiphy_register (char *name,
|
|
|
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);
|
|
|
- new_dev->name[name_len] = '\0';
|
|
|
+ new_dev->name = new_name = (char *)(new_dev + 1);
|
|
|
+ strncpy (new_name, name, name_len);
|
|
|
+ new_name[name_len] = '\0';
|
|
|
|
|
|
debug ("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
|
|
|
new_dev->name, new_dev->read, new_dev->write);
|
|
@@ -121,25 +141,20 @@ void miiphy_register (char *name,
|
|
|
current_mii = new_dev;
|
|
|
}
|
|
|
|
|
|
-int miiphy_set_current_dev (char *devname)
|
|
|
+int miiphy_set_current_dev(const char *devname)
|
|
|
{
|
|
|
- struct list_head *entry;
|
|
|
struct mii_dev *dev;
|
|
|
|
|
|
- list_for_each (entry, &mii_devs) {
|
|
|
- dev = list_entry (entry, struct mii_dev, link);
|
|
|
-
|
|
|
- if (strcmp (devname, dev->name) == 0) {
|
|
|
- current_mii = dev;
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ dev = miiphy_get_dev_by_name(devname, 0);
|
|
|
+ if (dev) {
|
|
|
+ current_mii = dev;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
- printf ("No such device: %s\n", devname);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-char *miiphy_get_current_dev ()
|
|
|
+const char *miiphy_get_current_dev(void)
|
|
|
{
|
|
|
if (current_mii)
|
|
|
return current_mii->name;
|
|
@@ -147,6 +162,20 @@ char *miiphy_get_current_dev ()
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static struct mii_dev *miiphy_get_active_dev(const char *devname)
|
|
|
+{
|
|
|
+ /* If the current mii is the one we want, return it */
|
|
|
+ if (current_mii)
|
|
|
+ if (strcmp(current_mii->name, devname) == 0)
|
|
|
+ return current_mii;
|
|
|
+
|
|
|
+ /* Otherwise, set the active one to the one we want */
|
|
|
+ if (miiphy_set_current_dev(devname))
|
|
|
+ return NULL;
|
|
|
+ else
|
|
|
+ return current_mii;
|
|
|
+}
|
|
|
+
|
|
|
/*****************************************************************************
|
|
|
*
|
|
|
* Read to variable <value> from the PHY attached to device <devname>,
|
|
@@ -155,33 +184,16 @@ char *miiphy_get_current_dev ()
|
|
|
* Returns:
|
|
|
* 0 on success
|
|
|
*/
|
|
|
-int miiphy_read (char *devname, unsigned char addr, unsigned char reg,
|
|
|
+int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
|
|
|
unsigned short *value)
|
|
|
{
|
|
|
- struct list_head *entry;
|
|
|
struct mii_dev *dev;
|
|
|
- int found_dev = 0;
|
|
|
- int read_ret = 0;
|
|
|
-
|
|
|
- if (!devname) {
|
|
|
- printf ("NULL device name!\n");
|
|
|
- return 1;
|
|
|
- }
|
|
|
-
|
|
|
- list_for_each (entry, &mii_devs) {
|
|
|
- dev = list_entry (entry, struct mii_dev, link);
|
|
|
-
|
|
|
- if (strcmp (devname, dev->name) == 0) {
|
|
|
- found_dev = 1;
|
|
|
- read_ret = dev->read (devname, addr, reg, value);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- if (found_dev == 0)
|
|
|
- printf ("No such device: %s\n", devname);
|
|
|
+ dev = miiphy_get_active_dev(devname);
|
|
|
+ if (dev)
|
|
|
+ return dev->read(devname, addr, reg, value);
|
|
|
|
|
|
- return ((found_dev) ? read_ret : 1);
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
@@ -192,33 +204,16 @@ 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(const char *devname, unsigned char addr, unsigned char reg,
|
|
|
unsigned short value)
|
|
|
{
|
|
|
- struct list_head *entry;
|
|
|
struct mii_dev *dev;
|
|
|
- int found_dev = 0;
|
|
|
- int write_ret = 0;
|
|
|
-
|
|
|
- if (!devname) {
|
|
|
- printf ("NULL device name!\n");
|
|
|
- return 1;
|
|
|
- }
|
|
|
-
|
|
|
- list_for_each (entry, &mii_devs) {
|
|
|
- dev = list_entry (entry, struct mii_dev, link);
|
|
|
-
|
|
|
- if (strcmp (devname, dev->name) == 0) {
|
|
|
- found_dev = 1;
|
|
|
- write_ret = dev->write (devname, addr, reg, value);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- if (found_dev == 0)
|
|
|
- printf ("No such device: %s\n", devname);
|
|
|
+ dev = miiphy_get_active_dev(devname);
|
|
|
+ if (dev)
|
|
|
+ return dev->write(devname, addr, reg, value);
|
|
|
|
|
|
- return ((found_dev) ? write_ret : 1);
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
@@ -252,7 +247,7 @@ void miiphy_listdev (void)
|
|
|
* Returns:
|
|
|
* 0 on success
|
|
|
*/
|
|
|
-int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
|
|
|
+int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
|
|
|
unsigned char *model, unsigned char *rev)
|
|
|
{
|
|
|
unsigned int reg = 0;
|
|
@@ -290,7 +285,7 @@ int miiphy_info (char *devname, unsigned char addr, unsigned int *oui,
|
|
|
* Returns:
|
|
|
* 0 on success
|
|
|
*/
|
|
|
-int miiphy_reset (char *devname, unsigned char addr)
|
|
|
+int miiphy_reset(const char *devname, unsigned char addr)
|
|
|
{
|
|
|
unsigned short reg;
|
|
|
int timeout = 500;
|
|
@@ -332,7 +327,7 @@ int miiphy_reset (char *devname, unsigned char addr)
|
|
|
*
|
|
|
* Determine the ethernet speed (10/100/1000). Return 10 on error.
|
|
|
*/
|
|
|
-int miiphy_speed (char *devname, unsigned char addr)
|
|
|
+int miiphy_speed(const char *devname, unsigned char addr)
|
|
|
{
|
|
|
u16 bmcr, anlpar;
|
|
|
|
|
@@ -386,7 +381,7 @@ miiphy_read_failed:
|
|
|
*
|
|
|
* Determine full/half duplex. Return half on error.
|
|
|
*/
|
|
|
-int miiphy_duplex (char *devname, unsigned char addr)
|
|
|
+int miiphy_duplex(const char *devname, unsigned char addr)
|
|
|
{
|
|
|
u16 bmcr, anlpar;
|
|
|
|
|
@@ -446,7 +441,7 @@ miiphy_read_failed:
|
|
|
* Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
|
|
|
* 1000BASE-T, or on error.
|
|
|
*/
|
|
|
-int miiphy_is_1000base_x (char *devname, unsigned char addr)
|
|
|
+int miiphy_is_1000base_x(const char *devname, unsigned char addr)
|
|
|
{
|
|
|
#if defined(CONFIG_PHY_GIGE)
|
|
|
u16 exsr;
|
|
@@ -467,7 +462,7 @@ int miiphy_is_1000base_x (char *devname, unsigned char addr)
|
|
|
*
|
|
|
* Determine link status
|
|
|
*/
|
|
|
-int miiphy_link (char *devname, unsigned char addr)
|
|
|
+int miiphy_link(const char *devname, unsigned char addr)
|
|
|
{
|
|
|
unsigned short reg;
|
|
|
|