cregit-Linux how code gets into the kernel

Release 4.11 drivers/net/phy/smsc.c

Directory: drivers/net/phy
/*
 * drivers/net/phy/smsc.c
 *
 * Driver for SMSC PHYs
 *
 * Author: Herbert Valerio Riedel
 *
 * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
 *
 * 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.
 *
 * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@shawell.net
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
#include <linux/smscphy.h>


struct smsc_phy_priv {
	
bool energy_enable;
};


static int smsc_phy_config_intr(struct phy_device *phydev) { int rc = phy_write (phydev, MII_LAN83C185_IM, ((PHY_INTERRUPT_ENABLED == phydev->interrupts) ? MII_LAN83C185_ISF_INT_PHYLIB_EVENTS : 0)); return rc < 0 ? rc : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Herbert Valerio Riedel4397.73%150.00%
Steve Glendinning12.27%150.00%
Total44100.00%2100.00%


static int smsc_phy_ack_interrupt(struct phy_device *phydev) { int rc = phy_read (phydev, MII_LAN83C185_ISF); return rc < 0 ? rc : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Herbert Valerio Riedel2996.67%150.00%
Steve Glendinning13.33%150.00%
Total30100.00%2100.00%


static int smsc_phy_config_init(struct phy_device *phydev) { struct smsc_phy_priv *priv = phydev->priv; int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); if (rc < 0) return rc; if (priv->energy_enable) { /* Enable energy detect mode for this SMSC Transceivers */ rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, rc | MII_LAN83C185_EDPWRDOWN); if (rc < 0) return rc; } return smsc_phy_ack_interrupt(phydev); }

Contributors

PersonTokensPropCommitsCommitProp
Gwenhael Goavec-Merou4255.26%116.67%
Heiko Schocher1215.79%116.67%
Herbert Valerio Riedel911.84%116.67%
Giuseppe Cavallaro67.89%116.67%
Teresa Remmet67.89%116.67%
Steve Glendinning11.32%116.67%
Total76100.00%6100.00%


static int smsc_phy_reset(struct phy_device *phydev) { int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES); if (rc < 0) return rc; /* If the SMSC PHY is in power down mode, then set it * in all capable mode before using it. */ if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN) { /* set "all capable" mode */ rc |= MII_LAN83C185_MODE_ALL; phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc); } /* reset the phy */ return genphy_soft_reset(phydev); }

Contributors

PersonTokensPropCommitsCommitProp
Philippe Reynes3046.88%125.00%
Gwenhael Goavec-Merou1726.56%125.00%
Giuseppe Cavallaro1320.31%125.00%
Manfred Schlaegl46.25%125.00%
Total64100.00%4100.00%


static int lan911x_config_init(struct phy_device *phydev) { return smsc_phy_ack_interrupt(phydev); }

Contributors

PersonTokensPropCommitsCommitProp
Patrick Trantham17100.00%1100.00%
Total17100.00%1100.00%

/* * The LAN87xx suffers from rare absence of the ENERGYON-bit when Ethernet cable * plugs in while LAN87xx is in Energy Detect Power-Down mode. This leads to * unstable detection of plugging in Ethernet cable. * This workaround disables Energy Detect Power-Down mode and waiting for * response on link pulses to detect presence of plugged Ethernet cable. * The Energy Detect Power-Down mode is enabled again in the end of procedure to * save approximately 220 mW of power if cable is unplugged. */
static int lan87xx_read_status(struct phy_device *phydev) { struct smsc_phy_priv *priv = phydev->priv; int err = genphy_read_status(phydev); if (!phydev->link && priv->energy_enable) { int i; /* Disable EDPD to wake up PHY */ int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); if (rc < 0) return rc; rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, rc & ~MII_LAN83C185_EDPWRDOWN); if (rc < 0) return rc; /* Wait max 640 ms to detect energy */ for (i = 0; i < 64; i++) { /* Sleep to allow link test pulses to be sent */ msleep(10); rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); if (rc < 0) return rc; if (rc & MII_LAN83C185_ENERGYON) break; } /* Re-enable EDPD */ rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); if (rc < 0) return rc; rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, rc | MII_LAN83C185_EDPWRDOWN); if (rc < 0) return rc; } return err; }

Contributors

PersonTokensPropCommitsCommitProp
Patrick Trantham6234.83%116.67%
Marek Vašut5028.09%116.67%
Igor Plyatov4324.16%116.67%
Teresa Remmet168.99%116.67%
Herbert Valerio Riedel63.37%116.67%
Giuseppe Cavallaro10.56%116.67%
Total178100.00%6100.00%


static int smsc_phy_probe(struct phy_device *phydev) { struct device *dev = &phydev->mdio.dev; struct device_node *of_node = dev->of_node; struct smsc_phy_priv *priv; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->energy_enable = true; if (of_property_read_bool(of_node, "smsc,disable-energy-detect")) priv->energy_enable = false; phydev->priv = priv; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Teresa Remmet91100.00%1100.00%
Total91100.00%1100.00%

static struct phy_driver smsc_phy_driver[] = { { .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */ .phy_id_mask = 0xfffffff0, .name = "SMSC LAN83C185", .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, .probe = smsc_phy_probe, /* basic functions */ .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .config_init = smsc_phy_config_init, .soft_reset = smsc_phy_reset, /* IRQ related */ .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, }, { .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */ .phy_id_mask = 0xfffffff0, .name = "SMSC LAN8187", .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, .probe = smsc_phy_probe, /* basic functions */ .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .config_init = smsc_phy_config_init, .soft_reset = smsc_phy_reset, /* IRQ related */ .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, }, { .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */ .phy_id_mask = 0xfffffff0, .name = "SMSC LAN8700", .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, .probe = smsc_phy_probe, /* basic functions */ .config_aneg = genphy_config_aneg, .read_status = lan87xx_read_status, .config_init = smsc_phy_config_init, .soft_reset = smsc_phy_reset, /* IRQ related */ .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, }, { .phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */ .phy_id_mask = 0xfffffff0, .name = "SMSC LAN911x Internal PHY", .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, .probe = smsc_phy_probe, /* basic functions */ .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .config_init = lan911x_config_init, /* IRQ related */ .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, }, { .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */ .phy_id_mask = 0xfffffff0, .name = "SMSC LAN8710/LAN8720", .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, .probe = smsc_phy_probe, /* basic functions */ .config_aneg = genphy_config_aneg, .read_status = lan87xx_read_status, .config_init = smsc_phy_config_init, .soft_reset = smsc_phy_reset, /* IRQ related */ .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, }, { .phy_id = 0x0007c110, .phy_id_mask = 0xfffffff0, .name = "SMSC LAN8740", .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, .probe = smsc_phy_probe, /* basic functions */ .config_aneg = genphy_config_aneg, .read_status = lan87xx_read_status, .config_init = smsc_phy_config_init, .soft_reset = smsc_phy_reset, /* IRQ related */ .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, } }; module_phy_driver(smsc_phy_driver); MODULE_DESCRIPTION("SMSC PHY driver"); MODULE_AUTHOR("Herbert Valerio Riedel"); MODULE_LICENSE("GPL"); static struct mdio_device_id __maybe_unused smsc_tbl[] = { { 0x0007c0a0, 0xfffffff0 }, { 0x0007c0b0, 0xfffffff0 }, { 0x0007c0c0, 0xfffffff0 }, { 0x0007c0d0, 0xfffffff0 }, { 0x0007c0f0, 0xfffffff0 }, { 0x0007c110, 0xfffffff0 }, { } }; MODULE_DEVICE_TABLE(mdio, smsc_tbl);

Overall Contributors

PersonTokensPropCommitsCommitProp
Steve Glendinning27826.01%625.00%
Herbert Valerio Riedel17916.74%14.17%
Teresa Remmet15114.13%14.17%
Patrick Trantham827.67%28.33%
Gwenhael Goavec-Merou797.39%14.17%
Joshua Henderson777.20%14.17%
Marek Vašut504.68%14.17%
David Woodhouse474.40%14.17%
Igor Plyatov454.21%14.17%
Philippe Reynes302.81%14.17%
Giuseppe Cavallaro211.96%14.17%
Heiko Schocher121.12%14.17%
Christian Hohnstaedt80.75%14.17%
Manfred Schlaegl40.37%14.17%
Javier Martinez Canillas30.28%14.17%
Johan Hovold10.09%14.17%
Uwe Kleine-König10.09%14.17%
Shruti Kanetkar10.09%14.17%
Total1069100.00%24100.00%
Directory: drivers/net/phy
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.