Patchwork [U-Boot,3/4] davinci: emac: add support for more than 1 PHYs

login
register
mail settings
Submitter nagabhushana.netagunte@ti.com
Date Sept. 30, 2011, 11:57 a.m.
Message ID <1317383832-23480-4-git-send-email-nagabhushana.netagunte@ti.com>
Download mbox | patch
Permalink /patch/117110/
State Changes Requested
Headers show

Comments

nagabhushana.netagunte@ti.com - Sept. 30, 2011, 11:57 a.m.
From: Nagabhushana Netagunte <nagabhushana.netagunte@ti.com>

add support for more than 1 PHYs. Many of the davinci platforms have more
than 1 PHYs on thier board. This patch extends support in davinci emac
driver for upto 3 PHYs.

Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
Signed-off-by: Nagabhushana Netagunte <nagabhushana.netagunte@ti.com>
---
 drivers/net/davinci_emac.c |  148 +++++++++++++++++++++++++++-----------------
 1 files changed, 90 insertions(+), 58 deletions(-)
Laurence Withers - Sept. 30, 2011, 8:29 p.m.
On Fri, Sep 30, 2011 at 05:27:11PM +0530, nagabhushana.netagunte@ti.com wrote:
> add support for more than 1 PHYs. Many of the davinci platforms have more
> than 1 PHYs on thier board. This patch extends support in davinci emac
> driver for upto 3 PHYs.

As a nitpick, there is a typo in "thier", which should be "their".

But a real question: where does the number 3 come from? It seems rather
arbitrary, at least without any explanatory comments. The MDIO interface can
support up to 31 devices, so perhaps you should allow for that many PHYs?
(Or perhaps a limit configurable with a #define, as it would seem wasteful
to allocate memory for 31 phy_t structures when I doubt there are any boards
that could truly take advantage of that).

Bye for now,
Wolfgang Denk - Oct. 6, 2011, 9:16 p.m.
Dear nagabhushana.netagunte@ti.com,

In message <1317383832-23480-4-git-send-email-nagabhushana.netagunte@ti.com> you wrote:
> From: Nagabhushana Netagunte <nagabhushana.netagunte@ti.com>
> 
> add support for more than 1 PHYs. Many of the davinci platforms have more
> than 1 PHYs on thier board. This patch extends support in davinci emac
> driver for upto 3 PHYs.
> 
> Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
> Signed-off-by: Nagabhushana Netagunte <nagabhushana.netagunte@ti.com>
> ---
>  drivers/net/davinci_emac.c |  148 +++++++++++++++++++++++++++-----------------
>  1 files changed, 90 insertions(+), 58 deletions(-)

Checkpatch says:

total: 0 errors, 2 warnings, 235 lines checked

Please clean up and resubmit.  Thanks.

Best regards,

Wolfgang Denk
Hadli, Manjunath - Oct. 11, 2011, 6:57 a.m.
Laurence,
On Sat, Oct 01, 2011 at 01:59:30, Laurence Withers wrote:
> On Fri, Sep 30, 2011 at 05:27:11PM +0530, nagabhushana.netagunte@ti.com wrote:
> > add support for more than 1 PHYs. Many of the davinci platforms have 
> > more than 1 PHYs on thier board. This patch extends support in davinci 
> > emac driver for upto 3 PHYs.
> 
> As a nitpick, there is a typo in "thier", which should be "their".
Thanks!

> 
> But a real question: where does the number 3 come from? It seems rather arbitrary, at least without any explanatory comments. The MDIO interface can support up to 31 devices, so perhaps you should allow for that many PHYs?
> (Or perhaps a limit configurable with a #define, as it would seem wasteful to allocate memory for 31 phy_t structures when I doubt there are any boards that could truly take advantage of that).
Agreed. The reason why it is 3 is because it is currently detecting only 3 at the max (on DA830), although the support is for 32 nos. We will #define it is 3 and latter boards can possibly change that depending on the board support.

Thx and Regards,
-Mat anju
> 
> Bye for now,
> -- 
> Laurence Withers, <lwithers@guralp.com>                http://www.guralp.com/
> Direct tel:+447753988197 or tel:+443333408643               Software Engineer
> General support queries: <support@guralp.com>         CMG-DCM CMG-EAM CMG-NAM
>

Patch

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 0d67a06..ed8fbfe 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -81,9 +81,12 @@  static int			emac_rx_queue_active = 0;
 static unsigned char		emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
 
 /* PHY address for a discovered PHY (0xff - not found) */
-static volatile u_int8_t	active_phy_addr = 0xff;
+static volatile u_int8_t	active_phy_addr[3] = { 0xff, 0xff, 0xff };
 
-phy_t				phy;
+/* number of PHY found active */
+static volatile u_int8_t	num_phy;
+
+phy_t				phy[3];
 
 static int davinci_eth_set_mac_addr(struct eth_device *dev)
 {
@@ -147,27 +150,30 @@  static int davinci_eth_phy_detect(void)
 {
 	u_int32_t	phy_act_state;
 	int		i;
+	int		j;
+	unsigned int	count = 0;
+
+	active_phy_addr[0] = 0xff;
+	active_phy_addr[1] = 0xff;
+	active_phy_addr[2] = 0xff;
 
-	active_phy_addr = 0xff;
+	udelay(1000);
+	phy_act_state = readl(&adap_mdio->ALIVE);
 
-	phy_act_state = readl(&adap_mdio->ALIVE) & EMAC_MDIO_PHY_MASK;
 	if (phy_act_state == 0)
-		return(0);				/* No active PHYs */
+		return 0;		/* No active PHYs */
 
 	debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
 
-	for (i = 0; i < 32; i++) {
+	for (i = 0, j = 0; i < 32; i++)
 		if (phy_act_state & (1 << i)) {
-			if (phy_act_state & ~(1 << i))
-				return(0);		/* More than one PHY */
-			else {
-				active_phy_addr = i;
-				return(1);
-			}
+			count++;
+			active_phy_addr[j++] = i;
 		}
-	}
 
-	return(0);	/* Just to make GCC happy */
+	num_phy = count;
+
+	return count;
 }
 
 
@@ -236,7 +242,18 @@  static int gen_is_phy_connected(int phy_addr)
 {
 	u_int16_t	dummy;
 
-	return(davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy));
+	return davinci_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy);
+}
+
+static int get_active_phy(void)
+{
+	int i;
+
+	for (i = 0; i < num_phy; i++)
+		if (phy[i].get_link_speed(active_phy_addr[i]))
+			return i;
+
+	return -1;	/* Return error if no link */
 }
 
 static int gen_get_link_speed(int phy_addr)
@@ -362,6 +379,7 @@  static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	dv_reg_p		addr;
 	u_int32_t		clkdiv, cnt;
 	volatile emac_desc	*rx_desc;
+	int			index;
 
 	debug_emac("+ emac_open\n");
 
@@ -460,7 +478,8 @@  static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	/* We need to wait for MDIO to start */
 	udelay(1000);
 
-	if (!phy.get_link_speed(active_phy_addr))
+	index = get_active_phy();
+	if (index == -1)
 		return(0);
 
 	emac_gigabit_enable();
@@ -559,12 +578,12 @@  static int davinci_eth_send_packet (struct eth_device *dev,
 					volatile void *packet, int length)
 {
 	int ret_status = -1;
-
+	int index;
 	tx_send_loop = 0;
 
-	/* Return error if no link */
-	if (!phy.get_link_speed (active_phy_addr)) {
-		printf ("WARN: emac_send_packet: No link\n");
+	index = get_active_phy();
+	if (index == -1) {
+		printf(" WARN: emac_send_packet: No link\n");
 		return (ret_status);
 	}
 
@@ -588,7 +607,7 @@  static int davinci_eth_send_packet (struct eth_device *dev,
 
 	/* Wait for packet to complete or link down */
 	while (1) {
-		if (!phy.get_link_speed (active_phy_addr)) {
+		if (!phy[index].get_link_speed(active_phy_addr[index])) {
 			davinci_eth_ch_teardown (EMAC_CH_TX);
 			return (ret_status);
 		}
@@ -685,6 +704,7 @@  int davinci_emac_initialize(void)
 	u_int32_t	phy_id;
 	u_int16_t	tmp;
 	int		i;
+	int		ret;
 	struct eth_device *dev;
 
 	dev = malloc(sizeof *dev);
@@ -709,7 +729,7 @@  int davinci_emac_initialize(void)
 	for (i = 0; i < 256; i++) {
 		if (readl(&adap_mdio->ALIVE))
 			break;
-		udelay(10);
+		udelay(1000);
 	}
 
 	if (i >= 256) {
@@ -717,57 +737,69 @@  int davinci_emac_initialize(void)
 		return(0);
 	}
 
-	/* Find if a PHY is connected and get it's address */
-	if (!davinci_eth_phy_detect())
+	/* Find if PHY(s) is/are connected */
+	ret = davinci_eth_phy_detect();
+	if (!ret)
 		return(0);
+	else
+		printf(" %d ETH PHY detected\n", ret);
 
 	/* Get PHY ID and initialize phy_ops for a detected PHY */
-	if (!davinci_eth_phy_read(active_phy_addr, MII_PHYSID1, &tmp)) {
-		active_phy_addr = 0xff;
-		return(0);
-	}
+	for (i = 0; i < num_phy; i++) {
+		if (!davinci_eth_phy_read(active_phy_addr[i], PHY_PHYIDR1,
+							&tmp)) {
+			active_phy_addr[i] = 0xff;
+			continue;
+		}
 
-	phy_id = (tmp << 16) & 0xffff0000;
+		phy_id = (tmp << 16) & 0xffff0000;
 
-	if (!davinci_eth_phy_read(active_phy_addr, MII_PHYSID2, &tmp)) {
-		active_phy_addr = 0xff;
-		return(0);
-	}
+		if (!davinci_eth_phy_read(active_phy_addr[i], PHY_PHYIDR2,
+							&tmp)) {
+			active_phy_addr[i] = 0xff;
+			continue;
+		}
 
-	phy_id |= tmp & 0x0000ffff;
+		phy_id |= tmp & 0x0000ffff;
 
-	switch (phy_id) {
+		switch (phy_id) {
 		case PHY_LXT972:
-			sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr);
-			phy.init = lxt972_init_phy;
-			phy.is_phy_connected = lxt972_is_phy_connected;
-			phy.get_link_speed = lxt972_get_link_speed;
-			phy.auto_negotiate = lxt972_auto_negotiate;
+			sprintf(phy[i].name, "LXT972 @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = lxt972_init_phy;
+			phy[i].is_phy_connected = lxt972_is_phy_connected;
+			phy[i].get_link_speed = lxt972_get_link_speed;
+			phy[i].auto_negotiate = lxt972_auto_negotiate;
 			break;
 		case PHY_DP83848:
-			sprintf(phy.name, "DP83848 @ 0x%02x", active_phy_addr);
-			phy.init = dp83848_init_phy;
-			phy.is_phy_connected = dp83848_is_phy_connected;
-			phy.get_link_speed = dp83848_get_link_speed;
-			phy.auto_negotiate = dp83848_auto_negotiate;
+			sprintf(phy[i].name, "DP83848 @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = dp83848_init_phy;
+			phy[i].is_phy_connected = dp83848_is_phy_connected;
+			phy[i].get_link_speed = dp83848_get_link_speed;
+			phy[i].auto_negotiate = dp83848_auto_negotiate;
 			break;
 		case PHY_ET1011C:
-			sprintf(phy.name, "ET1011C @ 0x%02x", active_phy_addr);
-			phy.init = gen_init_phy;
-			phy.is_phy_connected = gen_is_phy_connected;
-			phy.get_link_speed = et1011c_get_link_speed;
-			phy.auto_negotiate = gen_auto_negotiate;
+			sprintf(phy[i].name, "ET1011C @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = gen_init_phy;
+			phy[i].is_phy_connected = gen_is_phy_connected;
+			phy[i].get_link_speed = et1011c_get_link_speed;
+			phy[i].auto_negotiate = gen_auto_negotiate;
 			break;
 		default:
-			sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
-			phy.init = gen_init_phy;
-			phy.is_phy_connected = gen_is_phy_connected;
-			phy.get_link_speed = gen_get_link_speed;
-			phy.auto_negotiate = gen_auto_negotiate;
-	}
+			sprintf(phy[i].name, "GENERIC @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = gen_init_phy;
+			phy[i].is_phy_connected = gen_is_phy_connected;
+			phy[i].get_link_speed = gen_get_link_speed;
+			phy[i].auto_negotiate = gen_auto_negotiate;
+		}
 
-	printf("Ethernet PHY: %s\n", phy.name);
+		printf("Ethernet PHY: %s\n", phy[i].name);
 
-	miiphy_register(phy.name, davinci_mii_phy_read, davinci_mii_phy_write);
+		miiphy_register(phy[i].name, davinci_mii_phy_read,
+						davinci_mii_phy_write);
+	}
 	return(1);
 }