[PATCH net-next 08/10] drivers: net: xgene: Poll link status via GPIO
Quan Nguyen
qnguyen at apm.com
Sun Jul 31 22:39:35 PDT 2016
On Sat, Jul 30, 2016 at 7:34 AM, Iyappan Subramanian
<isubramanian at apm.com> wrote:
> When 10GbE SFP+ module is not plugged in or cable is not connected,
> the link status register does not report the proper state due
> to floating signal. This patch checks the module present status via an
> GPIO to determine whether to ignore the link status register and report
> link down.
>
> Signed-off-by: Quan Nguyen <qnguyen at apm.com>
> Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
> Tested-by: Fushen Chen <fchen at apm.com>
> ---
> drivers/net/ethernet/apm/xgene/Kconfig | 1 +
> drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 15 +++++++++++++++
> drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 1 +
> drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 6 ++++++
> 4 files changed, 23 insertions(+)
>
> diff --git a/drivers/net/ethernet/apm/xgene/Kconfig b/drivers/net/ethernet/apm/xgene/Kconfig
> index 300e3b5..6c60a7d 100644
> --- a/drivers/net/ethernet/apm/xgene/Kconfig
> +++ b/drivers/net/ethernet/apm/xgene/Kconfig
> @@ -4,6 +4,7 @@ config NET_XGENE
> depends on ARCH_XGENE || COMPILE_TEST
> select PHYLIB
> select MDIO_XGENE
> + select GPIO_XGENE_SB
I think this should change to GPIOLIB as we dont expected to work with
only gpio-xgene-sb.c. Other gpio drivers should be used as well.
> help
> This is the Ethernet driver for the on-chip ethernet interface on the
> APM X-Gene SoC.
> diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
> index 383e7ad..bda386d 100644
> --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
> +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
> @@ -19,6 +19,7 @@
> * along with this program. If not, see <http://www.gnu.org/licenses/>.
> */
>
> +#include <linux/gpio.h>
> #include "xgene_enet_main.h"
> #include "xgene_enet_hw.h"
> #include "xgene_enet_sgmac.h"
> @@ -1322,6 +1323,18 @@ static int xgene_enet_check_phy_handle(struct xgene_enet_pdata *pdata)
> return 0;
> }
>
> +static void xgene_enet_gpiod_get(struct xgene_enet_pdata *pdata)
> +{
> + struct device *dev = &pdata->pdev->dev;
> +
> + if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII)
> + return;
> +
> + pdata->sfp_rdy = gpiod_get(dev, "rxlos", GPIOD_IN);
> + if (IS_ERR(pdata->sfp_rdy))
> + pdata->sfp_rdy = gpiod_get(dev, "sfp", GPIOD_IN);
> +}
> +
> static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
> {
> struct platform_device *pdev;
> @@ -1411,6 +1424,8 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
> if (ret)
> return ret;
>
> + xgene_enet_gpiod_get(pdata);
> +
> pdata->clk = devm_clk_get(&pdev->dev, NULL);
> if (IS_ERR(pdata->clk)) {
> /* Firmware may have set up the clock already. */
> diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
> index 53f4a16..b339fc1 100644
> --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
> +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
> @@ -217,6 +217,7 @@ struct xgene_enet_pdata {
> u8 tx_delay;
> u8 rx_delay;
> bool mdio_driver;
> + struct gpio_desc *sfp_rdy;
> };
>
> struct xgene_indirect_ctl {
> diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
> index 4087dba..d672e71 100644
> --- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
> +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
> @@ -18,6 +18,8 @@
> * along with this program. If not, see <http://www.gnu.org/licenses/>.
> */
>
> +#include <linux/of_gpio.h>
> +#include <linux/gpio.h>
> #include "xgene_enet_main.h"
> #include "xgene_enet_hw.h"
> #include "xgene_enet_xgmac.h"
> @@ -399,10 +401,14 @@ static void xgene_enet_link_state(struct work_struct *work)
> {
> struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
> struct xgene_enet_pdata, link_work);
> + struct gpio_desc *sfp_rdy = pdata->sfp_rdy;
> struct net_device *ndev = pdata->ndev;
> u32 link_status, poll_interval;
>
> link_status = xgene_enet_link_status(pdata);
> + if (link_status && !IS_ERR(sfp_rdy) && !gpiod_get_value(sfp_rdy))
> + link_status = 0;
> +
> if (link_status) {
> if (!netif_carrier_ok(ndev)) {
> netif_carrier_on(ndev);
> --
> 1.9.1
>
More information about the linux-arm-kernel
mailing list