diff mbox

[OpenWrt-Devel,2/2] b53: support setting port link state

Message ID 1452106968-19278-2-git-send-email-zajec5@gmail.com
State Changes Requested
Headers show

Commit Message

Rafał Miłecki Jan. 6, 2016, 7:02 p.m. UTC
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 .../generic/files/drivers/net/phy/b53/b53_common.c | 40 ++++++++++++++++++++++
 1 file changed, 40 insertions(+)

Comments

Jonas Gorski Jan. 18, 2016, 1:21 p.m. UTC | #1
Hi,

On 6 January 2016 at 20:02, Rafał Miłecki <zajec5@gmail.com> wrote:
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
> ---
>  .../generic/files/drivers/net/phy/b53/b53_common.c | 40 ++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
>
> diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
> index 859d8d1..42a1679 100644
> --- a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
> +++ b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
> @@ -25,6 +25,7 @@
>  #include <linux/module.h>
>  #include <linux/switch.h>
>  #include <linux/platform_data/b53.h>
> +#include <uapi/linux/mii.h>
>
>  #include "b53_regs.h"
>  #include "b53_priv.h"
> @@ -794,6 +795,42 @@ static int b53_port_get_link(struct switch_dev *dev, int port,
>
>  }
>
> +static int b53_port_set_link(struct switch_dev *dev, int port,
> +                            struct switch_port_link *link)
> +{
> +       struct b53_device *priv = sw_to_b53(dev);
> +
> +       if (!priv->ops->phy_write16)
> +               return -ENOTSUPP;

Oh, you do the check here, that was unexpected.

You should also disallow reconfiguration of non-(e)phy ports like the cpu port.

> +
> +       if (link->aneg) {
> +               b53_phy_write16(priv, port, MII_BMCR, 0x0000);
> +               b53_phy_write16(priv, port, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
> +       } else {
> +               u16 bmcr = 0;
> +
> +               if (link->duplex)
> +                       bmcr |= BMCR_FULLDPLX;
> +
> +               switch (link->speed) {
> +               case SWITCH_PORT_SPEED_10:
> +                       break;
> +               case SWITCH_PORT_SPEED_100:
> +                       bmcr |= BMCR_SPEED100;
> +                       break;
> +               case SWITCH_PORT_SPEED_1000:
> +                       bmcr |= BMCR_SPEED1000;

b53 supports switches with fast ethernet only ports, so you need to
make sure that you don't try to set gige speed on them.

> +                       break;
> +               default:
> +                       return -ENOTSUPP;
> +               }
> +
> +               b53_phy_write16(priv, port, MII_BMCR, bmcr);
> +       }
> +
> +       return 0;

This function does nothing broadcom/b53 specific. I would think that
exposing the phys over the mdio bus is rather common for switches, so
I wonder if it wouldn't make more sense to have generic write/read mii
page function pointers for swconfig and move this function to the
swconfig common code.


Jonas
diff mbox

Patch

diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
index 859d8d1..42a1679 100644
--- a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
+++ b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
@@ -25,6 +25,7 @@ 
 #include <linux/module.h>
 #include <linux/switch.h>
 #include <linux/platform_data/b53.h>
+#include <uapi/linux/mii.h>
 
 #include "b53_regs.h"
 #include "b53_priv.h"
@@ -794,6 +795,42 @@  static int b53_port_get_link(struct switch_dev *dev, int port,
 
 }
 
+static int b53_port_set_link(struct switch_dev *dev, int port,
+			     struct switch_port_link *link)
+{
+	struct b53_device *priv = sw_to_b53(dev);
+
+	if (!priv->ops->phy_write16)
+		return -ENOTSUPP;
+
+	if (link->aneg) {
+		b53_phy_write16(priv, port, MII_BMCR, 0x0000);
+		b53_phy_write16(priv, port, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+	} else {
+		u16 bmcr = 0;
+
+		if (link->duplex)
+			bmcr |= BMCR_FULLDPLX;
+
+		switch (link->speed) {
+		case SWITCH_PORT_SPEED_10:
+			break;
+		case SWITCH_PORT_SPEED_100:
+			bmcr |= BMCR_SPEED100;
+			break;
+		case SWITCH_PORT_SPEED_1000:
+			bmcr |= BMCR_SPEED1000;
+			break;
+		default:
+			return -ENOTSUPP;
+		}
+
+		b53_phy_write16(priv, port, MII_BMCR, bmcr);
+	}
+
+	return 0;
+}
+
 static int b53_global_reset_switch(struct switch_dev *dev)
 {
 	struct b53_device *priv = sw_to_b53(dev);
@@ -1002,6 +1039,7 @@  static const struct switch_dev_ops b53_switch_ops_25 = {
 	.apply_config = b53_global_apply_config,
 	.reset_switch = b53_global_reset_switch,
 	.get_port_link = b53_port_get_link,
+	.set_port_link = b53_port_set_link,
 };
 
 static const struct switch_dev_ops b53_switch_ops_65 = {
@@ -1025,6 +1063,7 @@  static const struct switch_dev_ops b53_switch_ops_65 = {
 	.apply_config = b53_global_apply_config,
 	.reset_switch = b53_global_reset_switch,
 	.get_port_link = b53_port_get_link,
+	.set_port_link = b53_port_set_link,
 };
 
 static const struct switch_dev_ops b53_switch_ops = {
@@ -1048,6 +1087,7 @@  static const struct switch_dev_ops b53_switch_ops = {
 	.apply_config = b53_global_apply_config,
 	.reset_switch = b53_global_reset_switch,
 	.get_port_link = b53_port_get_link,
+	.set_port_link = b53_port_set_link,
 };
 
 struct b53_chip_data {