summaryrefslogtreecommitdiff
path: root/target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch')
-rw-r--r--target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch306
1 files changed, 306 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch b/target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch
new file mode 100644
index 0000000..00745f1
--- /dev/null
+++ b/target/linux/mvebu/patches-4.4/120-phy-move-fixed_phy-MII-register-generation-to-a-libr.patch
@@ -0,0 +1,306 @@
+From 4d5621372f6e7ddbfd5879602f82073987bcc722 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Sun, 20 Sep 2015 09:57:10 +0100
+Subject: [PATCH 709/744] phy: move fixed_phy MII register generation to a
+ library
+
+Move the fixed_phy MII register generation to a library to allow other
+software phy implementations to use this code.
+
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/net/phy/Kconfig | 4 ++
+ drivers/net/phy/Makefile | 3 +-
+ drivers/net/phy/fixed_phy.c | 95 ++-------------------------------
+ drivers/net/phy/swphy.c | 126 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/net/phy/swphy.h | 8 +++
+ 5 files changed, 143 insertions(+), 93 deletions(-)
+ create mode 100644 drivers/net/phy/swphy.c
+ create mode 100644 drivers/net/phy/swphy.h
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -26,6 +26,9 @@ config SWCONFIG_LEDS
+ bool "Switch LED trigger support"
+ depends on (SWCONFIG && LEDS_TRIGGERS)
+
++config SWPHY
++ bool
++
+ comment "MII PHY device drivers"
+
+ config AQUANTIA_PHY
+@@ -205,6 +208,7 @@ config RTL8306_PHY
+ config FIXED_PHY
+ tristate "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
+ depends on PHYLIB
++ select SWPHY
+ ---help---
+ Adds the platform "fixed" MDIO Bus to cover the boards that use
+ PHYs that are not connected to the real MDIO bus.
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -1,6 +1,7 @@
+ # Makefile for Linux PHY drivers
+
+-libphy-objs := phy.o phy_device.o mdio_bus.o
++libphy-y := phy.o phy_device.o mdio_bus.o
++libphy-$(CONFIG_SWPHY) += swphy.o
+
+ obj-$(CONFIG_MDIO_BOARDINFO) += mdio-boardinfo.o
+
+--- a/drivers/net/phy/fixed_phy.c
++++ b/drivers/net/phy/fixed_phy.c
+@@ -24,6 +24,8 @@
+ #include <linux/of.h>
+ #include <linux/gpio.h>
+
++#include "swphy.h"
++
+ #define MII_REGS_NUM 29
+
+ struct fixed_mdio_bus {
+@@ -49,101 +51,10 @@ static struct fixed_mdio_bus platform_fm
+
+ static int fixed_phy_update_regs(struct fixed_phy *fp)
+ {
+- u16 bmsr = BMSR_ANEGCAPABLE;
+- u16 bmcr = 0;
+- u16 lpagb = 0;
+- u16 lpa = 0;
+-
+ if (gpio_is_valid(fp->link_gpio))
+ fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
+
+- if (fp->status.duplex) {
+- switch (fp->status.speed) {
+- case 1000:
+- bmsr |= BMSR_ESTATEN;
+- break;
+- case 100:
+- bmsr |= BMSR_100FULL;
+- break;
+- case 10:
+- bmsr |= BMSR_10FULL;
+- break;
+- default:
+- break;
+- }
+- } else {
+- switch (fp->status.speed) {
+- case 1000:
+- bmsr |= BMSR_ESTATEN;
+- break;
+- case 100:
+- bmsr |= BMSR_100HALF;
+- break;
+- case 10:
+- bmsr |= BMSR_10HALF;
+- break;
+- default:
+- break;
+- }
+- }
+-
+- if (fp->status.link) {
+- bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
+-
+- if (fp->status.duplex) {
+- bmcr |= BMCR_FULLDPLX;
+-
+- switch (fp->status.speed) {
+- case 1000:
+- bmcr |= BMCR_SPEED1000;
+- lpagb |= LPA_1000FULL;
+- break;
+- case 100:
+- bmcr |= BMCR_SPEED100;
+- lpa |= LPA_100FULL;
+- break;
+- case 10:
+- lpa |= LPA_10FULL;
+- break;
+- default:
+- pr_warn("fixed phy: unknown speed\n");
+- return -EINVAL;
+- }
+- } else {
+- switch (fp->status.speed) {
+- case 1000:
+- bmcr |= BMCR_SPEED1000;
+- lpagb |= LPA_1000HALF;
+- break;
+- case 100:
+- bmcr |= BMCR_SPEED100;
+- lpa |= LPA_100HALF;
+- break;
+- case 10:
+- lpa |= LPA_10HALF;
+- break;
+- default:
+- pr_warn("fixed phy: unknown speed\n");
+- return -EINVAL;
+- }
+- }
+-
+- if (fp->status.pause)
+- lpa |= LPA_PAUSE_CAP;
+-
+- if (fp->status.asym_pause)
+- lpa |= LPA_PAUSE_ASYM;
+- }
+-
+- fp->regs[MII_PHYSID1] = 0;
+- fp->regs[MII_PHYSID2] = 0;
+-
+- fp->regs[MII_BMSR] = bmsr;
+- fp->regs[MII_BMCR] = bmcr;
+- fp->regs[MII_LPA] = lpa;
+- fp->regs[MII_STAT1000] = lpagb;
+-
+- return 0;
++ return swphy_update_regs(fp->regs, &fp->status);
+ }
+
+ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
+--- /dev/null
++++ b/drivers/net/phy/swphy.c
+@@ -0,0 +1,126 @@
++/*
++ * Software PHY emulation
++ *
++ * Code taken from fixed_phy.c by Russell King <rmk+kernel@arm.linux.org.uk>
++ *
++ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
++ * Anton Vorontsov <avorontsov@ru.mvista.com>
++ *
++ * Copyright (c) 2006-2007 MontaVista Software, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++#include <linux/export.h>
++#include <linux/mii.h>
++#include <linux/phy.h>
++#include <linux/phy_fixed.h>
++
++#include "swphy.h"
++
++/**
++ * swphy_update_regs - update MII register array with fixed phy state
++ * @regs: array of 32 registers to update
++ * @state: fixed phy status
++ *
++ * Update the array of MII registers with the fixed phy link, speed,
++ * duplex and pause mode settings.
++ */
++int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
++{
++ u16 bmsr = BMSR_ANEGCAPABLE;
++ u16 bmcr = 0;
++ u16 lpagb = 0;
++ u16 lpa = 0;
++
++ if (state->duplex) {
++ switch (state->speed) {
++ case 1000:
++ bmsr |= BMSR_ESTATEN;
++ break;
++ case 100:
++ bmsr |= BMSR_100FULL;
++ break;
++ case 10:
++ bmsr |= BMSR_10FULL;
++ break;
++ default:
++ break;
++ }
++ } else {
++ switch (state->speed) {
++ case 1000:
++ bmsr |= BMSR_ESTATEN;
++ break;
++ case 100:
++ bmsr |= BMSR_100HALF;
++ break;
++ case 10:
++ bmsr |= BMSR_10HALF;
++ break;
++ default:
++ break;
++ }
++ }
++
++ if (state->link) {
++ bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
++
++ if (state->duplex) {
++ bmcr |= BMCR_FULLDPLX;
++
++ switch (state->speed) {
++ case 1000:
++ bmcr |= BMCR_SPEED1000;
++ lpagb |= LPA_1000FULL;
++ break;
++ case 100:
++ bmcr |= BMCR_SPEED100;
++ lpa |= LPA_100FULL;
++ break;
++ case 10:
++ lpa |= LPA_10FULL;
++ break;
++ default:
++ pr_warn("swphy: unknown speed\n");
++ return -EINVAL;
++ }
++ } else {
++ switch (state->speed) {
++ case 1000:
++ bmcr |= BMCR_SPEED1000;
++ lpagb |= LPA_1000HALF;
++ break;
++ case 100:
++ bmcr |= BMCR_SPEED100;
++ lpa |= LPA_100HALF;
++ break;
++ case 10:
++ lpa |= LPA_10HALF;
++ break;
++ default:
++ pr_warn("swphy: unknown speed\n");
++ return -EINVAL;
++ }
++ }
++
++ if (state->pause)
++ lpa |= LPA_PAUSE_CAP;
++
++ if (state->asym_pause)
++ lpa |= LPA_PAUSE_ASYM;
++ }
++
++ regs[MII_PHYSID1] = 0;
++ regs[MII_PHYSID2] = 0;
++
++ regs[MII_BMSR] = bmsr;
++ regs[MII_BMCR] = bmcr;
++ regs[MII_LPA] = lpa;
++ regs[MII_STAT1000] = lpagb;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(swphy_update_regs);
+--- /dev/null
++++ b/drivers/net/phy/swphy.h
+@@ -0,0 +1,8 @@
++#ifndef SWPHY_H
++#define SWPHY_H
++
++struct fixed_phy_status;
++
++int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
++
++#endif