root/drivers/net/phy/teranetics.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. teranetics_aneg_done
  2. teranetics_read_status
  3. teranetics_match_phy_device

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Driver for Teranetics PHY
   4  *
   5  * Author: Shaohui Xie <Shaohui.Xie@freescale.com>
   6  *
   7  * Copyright 2015 Freescale Semiconductor, Inc.
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/mii.h>
  13 #include <linux/ethtool.h>
  14 #include <linux/mdio.h>
  15 #include <linux/phy.h>
  16 
  17 MODULE_DESCRIPTION("Teranetics PHY driver");
  18 MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");
  19 MODULE_LICENSE("GPL v2");
  20 
  21 #define PHY_ID_TN2020   0x00a19410
  22 #define MDIO_PHYXS_LNSTAT_SYNC0 0x0001
  23 #define MDIO_PHYXS_LNSTAT_SYNC1 0x0002
  24 #define MDIO_PHYXS_LNSTAT_SYNC2 0x0004
  25 #define MDIO_PHYXS_LNSTAT_SYNC3 0x0008
  26 #define MDIO_PHYXS_LNSTAT_ALIGN 0x1000
  27 
  28 #define MDIO_PHYXS_LANE_READY   (MDIO_PHYXS_LNSTAT_SYNC0 | \
  29                                 MDIO_PHYXS_LNSTAT_SYNC1 | \
  30                                 MDIO_PHYXS_LNSTAT_SYNC2 | \
  31                                 MDIO_PHYXS_LNSTAT_SYNC3 | \
  32                                 MDIO_PHYXS_LNSTAT_ALIGN)
  33 
  34 static int teranetics_aneg_done(struct phy_device *phydev)
  35 {
  36         /* auto negotiation state can only be checked when using copper
  37          * port, if using fiber port, just lie it's done.
  38          */
  39         if (!phy_read_mmd(phydev, MDIO_MMD_VEND1, 93))
  40                 return genphy_c45_aneg_done(phydev);
  41 
  42         return 1;
  43 }
  44 
  45 static int teranetics_read_status(struct phy_device *phydev)
  46 {
  47         int reg;
  48 
  49         phydev->link = 1;
  50 
  51         phydev->speed = SPEED_10000;
  52         phydev->duplex = DUPLEX_FULL;
  53 
  54         if (!phy_read_mmd(phydev, MDIO_MMD_VEND1, 93)) {
  55                 reg = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT);
  56                 if (reg < 0 ||
  57                     !((reg & MDIO_PHYXS_LANE_READY) == MDIO_PHYXS_LANE_READY)) {
  58                         phydev->link = 0;
  59                         return 0;
  60                 }
  61 
  62                 reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
  63                 if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
  64                         phydev->link = 0;
  65         }
  66 
  67         return 0;
  68 }
  69 
  70 static int teranetics_match_phy_device(struct phy_device *phydev)
  71 {
  72         return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020;
  73 }
  74 
  75 static struct phy_driver teranetics_driver[] = {
  76 {
  77         .phy_id         = PHY_ID_TN2020,
  78         .phy_id_mask    = 0xffffffff,
  79         .name           = "Teranetics TN2020",
  80         .features       = PHY_10GBIT_FEATURES,
  81         .soft_reset     = genphy_no_soft_reset,
  82         .aneg_done      = teranetics_aneg_done,
  83         .config_aneg    = gen10g_config_aneg,
  84         .read_status    = teranetics_read_status,
  85         .match_phy_device = teranetics_match_phy_device,
  86 },
  87 };
  88 
  89 module_phy_driver(teranetics_driver);
  90 
  91 static struct mdio_device_id __maybe_unused teranetics_tbl[] = {
  92         { PHY_ID_TN2020, 0xffffffff },
  93         { }
  94 };
  95 
  96 MODULE_DEVICE_TABLE(mdio, teranetics_tbl);

/* [<][>][^][v][top][bottom][index][help] */