diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/net/phy')
28 files changed, 0 insertions, 9828 deletions
diff --git a/ANDROID_3.4.5/drivers/net/phy/Kconfig b/ANDROID_3.4.5/drivers/net/phy/Kconfig deleted file mode 100644 index 0e01f4e5..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/Kconfig +++ /dev/null @@ -1,142 +0,0 @@ -# -# PHY Layer Configuration -# - -menuconfig PHYLIB - tristate "PHY Device support and infrastructure" - depends on !S390 - depends on NETDEVICES - help - Ethernet controllers are usually attached to PHY - devices. This option provides infrastructure for - managing PHY devices. - -if PHYLIB - -comment "MII PHY device drivers" - -config AMD_PHY - tristate "Drivers for the AMD PHYs" - ---help--- - Currently supports the am79c874 - -config MARVELL_PHY - tristate "Drivers for Marvell PHYs" - ---help--- - Currently has a driver for the 88E1011S - -config DAVICOM_PHY - tristate "Drivers for Davicom PHYs" - ---help--- - Currently supports dm9161e and dm9131 - -config QSEMI_PHY - tristate "Drivers for Quality Semiconductor PHYs" - ---help--- - Currently supports the qs6612 - -config LXT_PHY - tristate "Drivers for the Intel LXT PHYs" - ---help--- - Currently supports the lxt970, lxt971 - -config CICADA_PHY - tristate "Drivers for the Cicada PHYs" - ---help--- - Currently supports the cis8204 - -config VITESSE_PHY - tristate "Drivers for the Vitesse PHYs" - ---help--- - Currently supports the vsc8244 - -config SMSC_PHY - tristate "Drivers for SMSC PHYs" - ---help--- - Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs - -config BROADCOM_PHY - tristate "Drivers for Broadcom PHYs" - ---help--- - Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481 - and BCM5482 PHYs. - -config BCM63XX_PHY - tristate "Drivers for Broadcom 63xx SOCs internal PHY" - depends on BCM63XX - ---help--- - Currently supports the 6348 and 6358 PHYs. - -config ICPLUS_PHY - tristate "Drivers for ICPlus PHYs" - ---help--- - Currently supports the IP175C and IP1001 PHYs. - -config REALTEK_PHY - tristate "Drivers for Realtek PHYs" - ---help--- - Supports the Realtek 821x PHY. - -config NATIONAL_PHY - tristate "Drivers for National Semiconductor PHYs" - ---help--- - Currently supports the DP83865 PHY. - -config STE10XP - tristate "Driver for STMicroelectronics STe10Xp PHYs" - ---help--- - This is the driver for the STe100p and STe101p PHYs. - -config LSI_ET1011C_PHY - tristate "Driver for LSI ET1011C PHY" - ---help--- - Supports the LSI ET1011C PHY. - -config MICREL_PHY - tristate "Driver for Micrel PHYs" - ---help--- - Supports the KSZ9021, VSC8201, KS8001 PHYs. - -config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y - ---help--- - Adds the platform "fixed" MDIO Bus to cover the boards that use - PHYs that are not connected to the real MDIO bus. - - Currently tested with mpc866ads and mpc8349e-mitx. - -config MDIO_BITBANG - tristate "Support for bitbanged MDIO buses" - help - This module implements the MDIO bus protocol in software, - for use by low level drivers that export the ability to - drive the relevant pins. - - If in doubt, say N. - -config MDIO_GPIO - tristate "Support for GPIO lib-based bitbanged MDIO buses" - depends on MDIO_BITBANG && GENERIC_GPIO - ---help--- - Supports GPIO lib-based MDIO busses. - - To compile this driver as a module, choose M here: the module - will be called mdio-gpio. - -config MDIO_OCTEON - tristate "Support for MDIO buses on Octeon SOCs" - depends on CPU_CAVIUM_OCTEON - default y - help - - This module provides a driver for the Octeon MDIO busses. - It is required by the Octeon Ethernet device drivers. - - If in doubt, say Y. - -endif # PHYLIB - -config MICREL_KS8995MA - tristate "Micrel KS8995MA 5-ports 10/100 managed Ethernet switch" - depends on SPI diff --git a/ANDROID_3.4.5/drivers/net/phy/Makefile b/ANDROID_3.4.5/drivers/net/phy/Makefile deleted file mode 100644 index b7438b1b..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# Makefile for Linux PHY drivers - -libphy-objs := phy.o phy_device.o mdio_bus.o - -obj-$(CONFIG_PHYLIB) += libphy.o -obj-$(CONFIG_MARVELL_PHY) += marvell.o -obj-$(CONFIG_DAVICOM_PHY) += davicom.o -obj-$(CONFIG_CICADA_PHY) += cicada.o -obj-$(CONFIG_LXT_PHY) += lxt.o -obj-$(CONFIG_QSEMI_PHY) += qsemi.o -obj-$(CONFIG_SMSC_PHY) += smsc.o -obj-$(CONFIG_VITESSE_PHY) += vitesse.o -obj-$(CONFIG_BROADCOM_PHY) += broadcom.o -obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o -obj-$(CONFIG_ICPLUS_PHY) += icplus.o -obj-$(CONFIG_REALTEK_PHY) += realtek.o -obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o -obj-$(CONFIG_FIXED_PHY) += fixed.o -obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o -obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o -obj-$(CONFIG_NATIONAL_PHY) += national.o -obj-$(CONFIG_DP83640_PHY) += dp83640.o -obj-$(CONFIG_STE10XP) += ste10Xp.o -obj-$(CONFIG_MICREL_PHY) += micrel.o -obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o -obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o -obj-$(CONFIG_AMD_PHY) += amd.o diff --git a/ANDROID_3.4.5/drivers/net/phy/amd.c b/ANDROID_3.4.5/drivers/net/phy/amd.c deleted file mode 100644 index cfabd5fe..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/amd.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Driver for AMD am79c PHYs - * - * Author: Heiko Schocher <hs@denx.de> - * - * Copyright (c) 2011 DENX Software Engineering GmbH - * - * 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/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/phy.h> - -#define PHY_ID_AM79C874 0x0022561b - -#define MII_AM79C_IR 17 /* Interrupt Status/Control Register */ -#define MII_AM79C_IR_EN_LINK 0x0400 /* IR enable Linkstate */ -#define MII_AM79C_IR_EN_ANEG 0x0100 /* IR enable Aneg Complete */ -#define MII_AM79C_IR_IMASK_INIT (MII_AM79C_IR_EN_LINK | MII_AM79C_IR_EN_ANEG) - -MODULE_DESCRIPTION("AMD PHY driver"); -MODULE_AUTHOR("Heiko Schocher <hs@denx.de>"); -MODULE_LICENSE("GPL"); - -static int am79c_ack_interrupt(struct phy_device *phydev) -{ - int err; - - err = phy_read(phydev, MII_BMSR); - if (err < 0) - return err; - - err = phy_read(phydev, MII_AM79C_IR); - if (err < 0) - return err; - - return 0; -} - -static int am79c_config_init(struct phy_device *phydev) -{ - return 0; -} - -static int am79c_config_intr(struct phy_device *phydev) -{ - int err; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_AM79C_IR, MII_AM79C_IR_IMASK_INIT); - else - err = phy_write(phydev, MII_AM79C_IR, 0); - - return err; -} - -static struct phy_driver am79c_driver = { - .phy_id = PHY_ID_AM79C874, - .name = "AM79C874", - .phy_id_mask = 0xfffffff0, - .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = am79c_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = am79c_ack_interrupt, - .config_intr = am79c_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init am79c_init(void) -{ - int ret; - - ret = phy_driver_register(&am79c_driver); - if (ret) - return ret; - - return 0; -} - -static void __exit am79c_exit(void) -{ - phy_driver_unregister(&am79c_driver); -} - -module_init(am79c_init); -module_exit(am79c_exit); - -static struct mdio_device_id __maybe_unused amd_tbl[] = { - { PHY_ID_AM79C874, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, amd_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/bcm63xx.c b/ANDROID_3.4.5/drivers/net/phy/bcm63xx.c deleted file mode 100644 index e16f98cb..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/bcm63xx.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Driver for Broadcom 63xx SOCs integrated PHYs - * - * 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/module.h> -#include <linux/phy.h> - -#define MII_BCM63XX_IR 0x1a /* interrupt register */ -#define MII_BCM63XX_IR_EN 0x4000 /* global interrupt enable */ -#define MII_BCM63XX_IR_DUPLEX 0x0800 /* duplex changed */ -#define MII_BCM63XX_IR_SPEED 0x0400 /* speed changed */ -#define MII_BCM63XX_IR_LINK 0x0200 /* link changed */ -#define MII_BCM63XX_IR_GMASK 0x0100 /* global interrupt mask */ - -MODULE_DESCRIPTION("Broadcom 63xx internal PHY driver"); -MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>"); -MODULE_LICENSE("GPL"); - -static int bcm63xx_config_init(struct phy_device *phydev) -{ - int reg, err; - - reg = phy_read(phydev, MII_BCM63XX_IR); - if (reg < 0) - return reg; - - /* Mask interrupts globally. */ - reg |= MII_BCM63XX_IR_GMASK; - err = phy_write(phydev, MII_BCM63XX_IR, reg); - if (err < 0) - return err; - - /* Unmask events we are interested in */ - reg = ~(MII_BCM63XX_IR_DUPLEX | - MII_BCM63XX_IR_SPEED | - MII_BCM63XX_IR_LINK) | - MII_BCM63XX_IR_EN; - err = phy_write(phydev, MII_BCM63XX_IR, reg); - if (err < 0) - return err; - return 0; -} - -static int bcm63xx_ack_interrupt(struct phy_device *phydev) -{ - int reg; - - /* Clear pending interrupts. */ - reg = phy_read(phydev, MII_BCM63XX_IR); - if (reg < 0) - return reg; - - return 0; -} - -static int bcm63xx_config_intr(struct phy_device *phydev) -{ - int reg, err; - - reg = phy_read(phydev, MII_BCM63XX_IR); - if (reg < 0) - return reg; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - reg &= ~MII_BCM63XX_IR_GMASK; - else - reg |= MII_BCM63XX_IR_GMASK; - - err = phy_write(phydev, MII_BCM63XX_IR, reg); - return err; -} - -static struct phy_driver bcm63xx_1_driver = { - .phy_id = 0x00406000, - .phy_id_mask = 0xfffffc00, - .name = "Broadcom BCM63XX (1)", - /* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */ - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), - .flags = PHY_HAS_INTERRUPT, - .config_init = bcm63xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm63xx_ack_interrupt, - .config_intr = bcm63xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -/* same phy as above, with just a different OUI */ -static struct phy_driver bcm63xx_2_driver = { - .phy_id = 0x002bdc00, - .phy_id_mask = 0xfffffc00, - .name = "Broadcom BCM63XX (2)", - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), - .flags = PHY_HAS_INTERRUPT, - .config_init = bcm63xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm63xx_ack_interrupt, - .config_intr = bcm63xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static int __init bcm63xx_phy_init(void) -{ - int ret; - - ret = phy_driver_register(&bcm63xx_1_driver); - if (ret) - goto out_63xx_1; - ret = phy_driver_register(&bcm63xx_2_driver); - if (ret) - goto out_63xx_2; - return ret; - -out_63xx_2: - phy_driver_unregister(&bcm63xx_1_driver); -out_63xx_1: - return ret; -} - -static void __exit bcm63xx_phy_exit(void) -{ - phy_driver_unregister(&bcm63xx_1_driver); - phy_driver_unregister(&bcm63xx_2_driver); -} - -module_init(bcm63xx_phy_init); -module_exit(bcm63xx_phy_exit); - -static struct mdio_device_id __maybe_unused bcm63xx_tbl[] = { - { 0x00406000, 0xfffffc00 }, - { 0x002bdc00, 0xfffffc00 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, bcm63xx_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/broadcom.c b/ANDROID_3.4.5/drivers/net/phy/broadcom.c deleted file mode 100644 index 60338ff6..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/broadcom.c +++ /dev/null @@ -1,946 +0,0 @@ -/* - * drivers/net/phy/broadcom.c - * - * Broadcom BCM5411, BCM5421 and BCM5461 Gigabit Ethernet - * transceivers. - * - * Copyright (c) 2006 Maciej W. Rozycki - * - * Inspired by code written by Amy Fong. - * - * 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/module.h> -#include <linux/phy.h> -#include <linux/brcmphy.h> - - -#define BRCM_PHY_MODEL(phydev) \ - ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) - -#define BRCM_PHY_REV(phydev) \ - ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask)) - - -#define MII_BCM54XX_ECR 0x10 /* BCM54xx extended control register */ -#define MII_BCM54XX_ECR_IM 0x1000 /* Interrupt mask */ -#define MII_BCM54XX_ECR_IF 0x0800 /* Interrupt force */ - -#define MII_BCM54XX_ESR 0x11 /* BCM54xx extended status register */ -#define MII_BCM54XX_ESR_IS 0x1000 /* Interrupt status */ - -#define MII_BCM54XX_EXP_DATA 0x15 /* Expansion register data */ -#define MII_BCM54XX_EXP_SEL 0x17 /* Expansion register select */ -#define MII_BCM54XX_EXP_SEL_SSD 0x0e00 /* Secondary SerDes select */ -#define MII_BCM54XX_EXP_SEL_ER 0x0f00 /* Expansion register select */ - -#define MII_BCM54XX_AUX_CTL 0x18 /* Auxiliary control register */ -#define MII_BCM54XX_ISR 0x1a /* BCM54xx interrupt status register */ -#define MII_BCM54XX_IMR 0x1b /* BCM54xx interrupt mask register */ -#define MII_BCM54XX_INT_CRCERR 0x0001 /* CRC error */ -#define MII_BCM54XX_INT_LINK 0x0002 /* Link status changed */ -#define MII_BCM54XX_INT_SPEED 0x0004 /* Link speed change */ -#define MII_BCM54XX_INT_DUPLEX 0x0008 /* Duplex mode changed */ -#define MII_BCM54XX_INT_LRS 0x0010 /* Local receiver status changed */ -#define MII_BCM54XX_INT_RRS 0x0020 /* Remote receiver status changed */ -#define MII_BCM54XX_INT_SSERR 0x0040 /* Scrambler synchronization error */ -#define MII_BCM54XX_INT_UHCD 0x0080 /* Unsupported HCD negotiated */ -#define MII_BCM54XX_INT_NHCD 0x0100 /* No HCD */ -#define MII_BCM54XX_INT_NHCDL 0x0200 /* No HCD link */ -#define MII_BCM54XX_INT_ANPR 0x0400 /* Auto-negotiation page received */ -#define MII_BCM54XX_INT_LC 0x0800 /* All counters below 128 */ -#define MII_BCM54XX_INT_HC 0x1000 /* Counter above 32768 */ -#define MII_BCM54XX_INT_MDIX 0x2000 /* MDIX status change */ -#define MII_BCM54XX_INT_PSERR 0x4000 /* Pair swap error */ - -#define MII_BCM54XX_SHD 0x1c /* 0x1c shadow registers */ -#define MII_BCM54XX_SHD_WRITE 0x8000 -#define MII_BCM54XX_SHD_VAL(x) ((x & 0x1f) << 10) -#define MII_BCM54XX_SHD_DATA(x) ((x & 0x3ff) << 0) - -/* - * AUXILIARY CONTROL SHADOW ACCESS REGISTERS. (PHY REG 0x18) - */ -#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x0000 -#define MII_BCM54XX_AUXCTL_ACTL_TX_6DB 0x0400 -#define MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA 0x0800 - -#define MII_BCM54XX_AUXCTL_MISC_WREN 0x8000 -#define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX 0x0200 -#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000 -#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007 - -#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x0000 - - -/* - * Broadcom LED source encodings. These are used in BCM5461, BCM5481, - * BCM5482, and possibly some others. - */ -#define BCM_LED_SRC_LINKSPD1 0x0 -#define BCM_LED_SRC_LINKSPD2 0x1 -#define BCM_LED_SRC_XMITLED 0x2 -#define BCM_LED_SRC_ACTIVITYLED 0x3 -#define BCM_LED_SRC_FDXLED 0x4 -#define BCM_LED_SRC_SLAVE 0x5 -#define BCM_LED_SRC_INTR 0x6 -#define BCM_LED_SRC_QUALITY 0x7 -#define BCM_LED_SRC_RCVLED 0x8 -#define BCM_LED_SRC_MULTICOLOR1 0xa -#define BCM_LED_SRC_OPENSHORT 0xb -#define BCM_LED_SRC_OFF 0xe /* Tied high */ -#define BCM_LED_SRC_ON 0xf /* Tied low */ - - -/* - * BCM5482: Shadow registers - * Shadow values go into bits [14:10] of register 0x1c to select a shadow - * register to access. - */ -/* 00101: Spare Control Register 3 */ -#define BCM54XX_SHD_SCR3 0x05 -#define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001 -#define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002 -#define BCM54XX_SHD_SCR3_TRDDAPD 0x0004 - -/* 01010: Auto Power-Down */ -#define BCM54XX_SHD_APD 0x0a -#define BCM54XX_SHD_APD_EN 0x0020 - -#define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ - /* LED3 / ~LINKSPD[2] selector */ -#define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4) - /* LED1 / ~LINKSPD[1] selector */ -#define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0) -#define BCM54XX_SHD_RGMII_MODE 0x0b /* 01011: RGMII Mode Selector */ -#define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */ -#define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */ -#define BCM5482_SHD_SSD_EN 0x0001 /* SSD enable */ -#define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */ -#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */ - - -/* - * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17) - */ -#define MII_BCM54XX_EXP_AADJ1CH0 0x001f -#define MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN 0x0200 -#define MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF 0x0100 -#define MII_BCM54XX_EXP_AADJ1CH3 0x601f -#define MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ 0x0002 -#define MII_BCM54XX_EXP_EXP08 0x0F08 -#define MII_BCM54XX_EXP_EXP08_RJCT_2MHZ 0x0001 -#define MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE 0x0200 -#define MII_BCM54XX_EXP_EXP75 0x0f75 -#define MII_BCM54XX_EXP_EXP75_VDACCTRL 0x003c -#define MII_BCM54XX_EXP_EXP75_CM_OSC 0x0001 -#define MII_BCM54XX_EXP_EXP96 0x0f96 -#define MII_BCM54XX_EXP_EXP96_MYST 0x0010 -#define MII_BCM54XX_EXP_EXP97 0x0f97 -#define MII_BCM54XX_EXP_EXP97_MYST 0x0c0c - -/* - * BCM5482: Secondary SerDes registers - */ -#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */ -#define BCM5482_SSD_1000BX_CTL_PWRDOWN 0x0800 /* Power-down SSD */ -#define BCM5482_SSD_SGMII_SLAVE 0x15 /* SGMII Slave Register */ -#define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */ -#define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */ - - -/*****************************************************************************/ -/* Fast Ethernet Transceiver definitions. */ -/*****************************************************************************/ - -#define MII_BRCM_FET_INTREG 0x1a /* Interrupt register */ -#define MII_BRCM_FET_IR_MASK 0x0100 /* Mask all interrupts */ -#define MII_BRCM_FET_IR_LINK_EN 0x0200 /* Link status change enable */ -#define MII_BRCM_FET_IR_SPEED_EN 0x0400 /* Link speed change enable */ -#define MII_BRCM_FET_IR_DUPLEX_EN 0x0800 /* Duplex mode change enable */ -#define MII_BRCM_FET_IR_ENABLE 0x4000 /* Interrupt enable */ - -#define MII_BRCM_FET_BRCMTEST 0x1f /* Brcm test register */ -#define MII_BRCM_FET_BT_SRE 0x0080 /* Shadow register enable */ - - -/*** Shadow register definitions ***/ - -#define MII_BRCM_FET_SHDW_MISCCTRL 0x10 /* Shadow misc ctrl */ -#define MII_BRCM_FET_SHDW_MC_FAME 0x4000 /* Force Auto MDIX enable */ - -#define MII_BRCM_FET_SHDW_AUXMODE4 0x1a /* Auxiliary mode 4 */ -#define MII_BRCM_FET_SHDW_AM4_LED_MASK 0x0003 -#define MII_BRCM_FET_SHDW_AM4_LED_MODE1 0x0001 - -#define MII_BRCM_FET_SHDW_AUXSTAT2 0x1b /* Auxiliary status 2 */ -#define MII_BRCM_FET_SHDW_AS2_APDE 0x0020 /* Auto power down enable */ - - -MODULE_DESCRIPTION("Broadcom PHY driver"); -MODULE_AUTHOR("Maciej W. Rozycki"); -MODULE_LICENSE("GPL"); - -/* - * Indirect register access functions for the 1000BASE-T/100BASE-TX/10BASE-T - * 0x1c shadow registers. - */ -static int bcm54xx_shadow_read(struct phy_device *phydev, u16 shadow) -{ - phy_write(phydev, MII_BCM54XX_SHD, MII_BCM54XX_SHD_VAL(shadow)); - return MII_BCM54XX_SHD_DATA(phy_read(phydev, MII_BCM54XX_SHD)); -} - -static int bcm54xx_shadow_write(struct phy_device *phydev, u16 shadow, u16 val) -{ - return phy_write(phydev, MII_BCM54XX_SHD, - MII_BCM54XX_SHD_WRITE | - MII_BCM54XX_SHD_VAL(shadow) | - MII_BCM54XX_SHD_DATA(val)); -} - -/* Indirect register access functions for the Expansion Registers */ -static int bcm54xx_exp_read(struct phy_device *phydev, u16 regnum) -{ - int val; - - val = phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum); - if (val < 0) - return val; - - val = phy_read(phydev, MII_BCM54XX_EXP_DATA); - - /* Restore default value. It's O.K. if this write fails. */ - phy_write(phydev, MII_BCM54XX_EXP_SEL, 0); - - return val; -} - -static int bcm54xx_exp_write(struct phy_device *phydev, u16 regnum, u16 val) -{ - int ret; - - ret = phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum); - if (ret < 0) - return ret; - - ret = phy_write(phydev, MII_BCM54XX_EXP_DATA, val); - - /* Restore default value. It's O.K. if this write fails. */ - phy_write(phydev, MII_BCM54XX_EXP_SEL, 0); - - return ret; -} - -static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) -{ - return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); -} - -/* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ -static int bcm50610_a0_workaround(struct phy_device *phydev) -{ - int err; - - err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH0, - MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN | - MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF); - if (err < 0) - return err; - - err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH3, - MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ); - if (err < 0) - return err; - - err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, - MII_BCM54XX_EXP_EXP75_VDACCTRL); - if (err < 0) - return err; - - err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP96, - MII_BCM54XX_EXP_EXP96_MYST); - if (err < 0) - return err; - - err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP97, - MII_BCM54XX_EXP_EXP97_MYST); - - return err; -} - -static int bcm54xx_phydsp_config(struct phy_device *phydev) -{ - int err, err2; - - /* Enable the SMDSP clock */ - err = bcm54xx_auxctl_write(phydev, - MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL, - MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA | - MII_BCM54XX_AUXCTL_ACTL_TX_6DB); - if (err < 0) - return err; - - if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || - BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) { - /* Clear bit 9 to fix a phy interop issue. */ - err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08, - MII_BCM54XX_EXP_EXP08_RJCT_2MHZ); - if (err < 0) - goto error; - - if (phydev->drv->phy_id == PHY_ID_BCM50610) { - err = bcm50610_a0_workaround(phydev); - if (err < 0) - goto error; - } - } - - if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) { - int val; - - val = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75); - if (val < 0) - goto error; - - val |= MII_BCM54XX_EXP_EXP75_CM_OSC; - err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, val); - } - -error: - /* Disable the SMDSP clock */ - err2 = bcm54xx_auxctl_write(phydev, - MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL, - MII_BCM54XX_AUXCTL_ACTL_TX_6DB); - - /* Return the first error reported. */ - return err ? err : err2; -} - -static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) -{ - u32 orig; - int val; - bool clk125en = true; - - /* Abort if we are using an untested phy. */ - if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 && - BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 && - BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) - return; - - val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_SCR3); - if (val < 0) - return; - - orig = val; - - if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || - BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && - BRCM_PHY_REV(phydev) >= 0x3) { - /* - * Here, bit 0 _disables_ CLK125 when set. - * This bit is set by default. - */ - clk125en = false; - } else { - if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) { - /* Here, bit 0 _enables_ CLK125 when set */ - val &= ~BCM54XX_SHD_SCR3_DEF_CLK125; - clk125en = false; - } - } - - if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) - val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS; - else - val |= BCM54XX_SHD_SCR3_DLLAPD_DIS; - - if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) - val |= BCM54XX_SHD_SCR3_TRDDAPD; - - if (orig != val) - bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val); - - val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_APD); - if (val < 0) - return; - - orig = val; - - if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) - val |= BCM54XX_SHD_APD_EN; - else - val &= ~BCM54XX_SHD_APD_EN; - - if (orig != val) - bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val); -} - -static int bcm54xx_config_init(struct phy_device *phydev) -{ - int reg, err; - - reg = phy_read(phydev, MII_BCM54XX_ECR); - if (reg < 0) - return reg; - - /* Mask interrupts globally. */ - reg |= MII_BCM54XX_ECR_IM; - err = phy_write(phydev, MII_BCM54XX_ECR, reg); - if (err < 0) - return err; - - /* Unmask events we are interested in. */ - reg = ~(MII_BCM54XX_INT_DUPLEX | - MII_BCM54XX_INT_SPEED | - MII_BCM54XX_INT_LINK); - err = phy_write(phydev, MII_BCM54XX_IMR, reg); - if (err < 0) - return err; - - if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 || - BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) && - (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE)) - bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0); - - if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) || - (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) || - (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) - bcm54xx_adjust_rxrefclk(phydev); - - bcm54xx_phydsp_config(phydev); - - return 0; -} - -static int bcm5482_config_init(struct phy_device *phydev) -{ - int err, reg; - - err = bcm54xx_config_init(phydev); - - if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) { - /* - * Enable secondary SerDes and its use as an LED source - */ - reg = bcm54xx_shadow_read(phydev, BCM5482_SHD_SSD); - bcm54xx_shadow_write(phydev, BCM5482_SHD_SSD, - reg | - BCM5482_SHD_SSD_LEDM | - BCM5482_SHD_SSD_EN); - - /* - * Enable SGMII slave mode and auto-detection - */ - reg = BCM5482_SSD_SGMII_SLAVE | MII_BCM54XX_EXP_SEL_SSD; - err = bcm54xx_exp_read(phydev, reg); - if (err < 0) - return err; - err = bcm54xx_exp_write(phydev, reg, err | - BCM5482_SSD_SGMII_SLAVE_EN | - BCM5482_SSD_SGMII_SLAVE_AD); - if (err < 0) - return err; - - /* - * Disable secondary SerDes powerdown - */ - reg = BCM5482_SSD_1000BX_CTL | MII_BCM54XX_EXP_SEL_SSD; - err = bcm54xx_exp_read(phydev, reg); - if (err < 0) - return err; - err = bcm54xx_exp_write(phydev, reg, - err & ~BCM5482_SSD_1000BX_CTL_PWRDOWN); - if (err < 0) - return err; - - /* - * Select 1000BASE-X register set (primary SerDes) - */ - reg = bcm54xx_shadow_read(phydev, BCM5482_SHD_MODE); - bcm54xx_shadow_write(phydev, BCM5482_SHD_MODE, - reg | BCM5482_SHD_MODE_1000BX); - - /* - * LED1=ACTIVITYLED, LED3=LINKSPD[2] - * (Use LED1 as secondary SerDes ACTIVITY LED) - */ - bcm54xx_shadow_write(phydev, BCM5482_SHD_LEDS1, - BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) | - BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD2)); - - /* - * Auto-negotiation doesn't seem to work quite right - * in this mode, so we disable it and force it to the - * right speed/duplex setting. Only 'link status' - * is important. - */ - phydev->autoneg = AUTONEG_DISABLE; - phydev->speed = SPEED_1000; - phydev->duplex = DUPLEX_FULL; - } - - return err; -} - -static int bcm5482_read_status(struct phy_device *phydev) -{ - int err; - - err = genphy_read_status(phydev); - - if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) { - /* - * Only link status matters for 1000Base-X mode, so force - * 1000 Mbit/s full-duplex status - */ - if (phydev->link) { - phydev->speed = SPEED_1000; - phydev->duplex = DUPLEX_FULL; - } - } - - return err; -} - -static int bcm54xx_ack_interrupt(struct phy_device *phydev) -{ - int reg; - - /* Clear pending interrupts. */ - reg = phy_read(phydev, MII_BCM54XX_ISR); - if (reg < 0) - return reg; - - return 0; -} - -static int bcm54xx_config_intr(struct phy_device *phydev) -{ - int reg, err; - - reg = phy_read(phydev, MII_BCM54XX_ECR); - if (reg < 0) - return reg; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - reg &= ~MII_BCM54XX_ECR_IM; - else - reg |= MII_BCM54XX_ECR_IM; - - err = phy_write(phydev, MII_BCM54XX_ECR, reg); - return err; -} - -static int bcm5481_config_aneg(struct phy_device *phydev) -{ - int ret; - - /* Aneg firsly. */ - ret = genphy_config_aneg(phydev); - - /* Then we can set up the delay. */ - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { - u16 reg; - - /* - * There is no BCM5481 specification available, so down - * here is everything we know about "register 0x18". This - * at least helps BCM5481 to successfully receive packets - * on MPC8360E-RDK board. Peter Barada <peterb@logicpd.com> - * says: "This sets delay between the RXD and RXC signals - * instead of using trace lengths to achieve timing". - */ - - /* Set RDX clk delay. */ - reg = 0x7 | (0x7 << 12); - phy_write(phydev, 0x18, reg); - - reg = phy_read(phydev, 0x18); - /* Set RDX-RXC skew. */ - reg |= (1 << 8); - /* Write bits 14:0. */ - reg |= (1 << 15); - phy_write(phydev, 0x18, reg); - } - - return ret; -} - -static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set) -{ - int val; - - val = phy_read(phydev, reg); - if (val < 0) - return val; - - return phy_write(phydev, reg, val | set); -} - -static int brcm_fet_config_init(struct phy_device *phydev) -{ - int reg, err, err2, brcmtest; - - /* Reset the PHY to bring it to a known state. */ - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - - reg = phy_read(phydev, MII_BRCM_FET_INTREG); - if (reg < 0) - return reg; - - /* Unmask events we are interested in and mask interrupts globally. */ - reg = MII_BRCM_FET_IR_DUPLEX_EN | - MII_BRCM_FET_IR_SPEED_EN | - MII_BRCM_FET_IR_LINK_EN | - MII_BRCM_FET_IR_ENABLE | - MII_BRCM_FET_IR_MASK; - - err = phy_write(phydev, MII_BRCM_FET_INTREG, reg); - if (err < 0) - return err; - - /* Enable shadow register access */ - brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST); - if (brcmtest < 0) - return brcmtest; - - reg = brcmtest | MII_BRCM_FET_BT_SRE; - - err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg); - if (err < 0) - return err; - - /* Set the LED mode */ - reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4); - if (reg < 0) { - err = reg; - goto done; - } - - reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK; - reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1; - - err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg); - if (err < 0) - goto done; - - /* Enable auto MDIX */ - err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL, - MII_BRCM_FET_SHDW_MC_FAME); - if (err < 0) - goto done; - - if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) { - /* Enable auto power down */ - err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2, - MII_BRCM_FET_SHDW_AS2_APDE); - } - -done: - /* Disable shadow register access */ - err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest); - if (!err) - err = err2; - - return err; -} - -static int brcm_fet_ack_interrupt(struct phy_device *phydev) -{ - int reg; - - /* Clear pending interrupts. */ - reg = phy_read(phydev, MII_BRCM_FET_INTREG); - if (reg < 0) - return reg; - - return 0; -} - -static int brcm_fet_config_intr(struct phy_device *phydev) -{ - int reg, err; - - reg = phy_read(phydev, MII_BRCM_FET_INTREG); - if (reg < 0) - return reg; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - reg &= ~MII_BRCM_FET_IR_MASK; - else - reg |= MII_BRCM_FET_IR_MASK; - - err = phy_write(phydev, MII_BRCM_FET_INTREG, reg); - return err; -} - -static struct phy_driver bcm5411_driver = { - .phy_id = PHY_ID_BCM5411, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5411", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm5421_driver = { - .phy_id = PHY_ID_BCM5421, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5421", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm5461_driver = { - .phy_id = PHY_ID_BCM5461, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5461", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm5464_driver = { - .phy_id = PHY_ID_BCM5464, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5464", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm5481_driver = { - .phy_id = PHY_ID_BCM5481, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5481", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = bcm5481_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm5482_driver = { - .phy_id = PHY_ID_BCM5482, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5482", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm5482_config_init, - .config_aneg = genphy_config_aneg, - .read_status = bcm5482_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm50610_driver = { - .phy_id = PHY_ID_BCM50610, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM50610", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm50610m_driver = { - .phy_id = PHY_ID_BCM50610M, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM50610M", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm57780_driver = { - .phy_id = PHY_ID_BCM57780, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM57780", - .features = PHY_GBIT_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = bcm54xx_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = bcm54xx_ack_interrupt, - .config_intr = bcm54xx_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcmac131_driver = { - .phy_id = PHY_ID_BCMAC131, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCMAC131", - .features = PHY_BASIC_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = brcm_fet_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = brcm_fet_ack_interrupt, - .config_intr = brcm_fet_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static struct phy_driver bcm5241_driver = { - .phy_id = PHY_ID_BCM5241, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5241", - .features = PHY_BASIC_FEATURES | - SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = brcm_fet_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = brcm_fet_ack_interrupt, - .config_intr = brcm_fet_config_intr, - .driver = { .owner = THIS_MODULE }, -}; - -static int __init broadcom_init(void) -{ - int ret; - - ret = phy_driver_register(&bcm5411_driver); - if (ret) - goto out_5411; - ret = phy_driver_register(&bcm5421_driver); - if (ret) - goto out_5421; - ret = phy_driver_register(&bcm5461_driver); - if (ret) - goto out_5461; - ret = phy_driver_register(&bcm5464_driver); - if (ret) - goto out_5464; - ret = phy_driver_register(&bcm5481_driver); - if (ret) - goto out_5481; - ret = phy_driver_register(&bcm5482_driver); - if (ret) - goto out_5482; - ret = phy_driver_register(&bcm50610_driver); - if (ret) - goto out_50610; - ret = phy_driver_register(&bcm50610m_driver); - if (ret) - goto out_50610m; - ret = phy_driver_register(&bcm57780_driver); - if (ret) - goto out_57780; - ret = phy_driver_register(&bcmac131_driver); - if (ret) - goto out_ac131; - ret = phy_driver_register(&bcm5241_driver); - if (ret) - goto out_5241; - return ret; - -out_5241: - phy_driver_unregister(&bcmac131_driver); -out_ac131: - phy_driver_unregister(&bcm57780_driver); -out_57780: - phy_driver_unregister(&bcm50610m_driver); -out_50610m: - phy_driver_unregister(&bcm50610_driver); -out_50610: - phy_driver_unregister(&bcm5482_driver); -out_5482: - phy_driver_unregister(&bcm5481_driver); -out_5481: - phy_driver_unregister(&bcm5464_driver); -out_5464: - phy_driver_unregister(&bcm5461_driver); -out_5461: - phy_driver_unregister(&bcm5421_driver); -out_5421: - phy_driver_unregister(&bcm5411_driver); -out_5411: - return ret; -} - -static void __exit broadcom_exit(void) -{ - phy_driver_unregister(&bcm5241_driver); - phy_driver_unregister(&bcmac131_driver); - phy_driver_unregister(&bcm57780_driver); - phy_driver_unregister(&bcm50610m_driver); - phy_driver_unregister(&bcm50610_driver); - phy_driver_unregister(&bcm5482_driver); - phy_driver_unregister(&bcm5481_driver); - phy_driver_unregister(&bcm5464_driver); - phy_driver_unregister(&bcm5461_driver); - phy_driver_unregister(&bcm5421_driver); - phy_driver_unregister(&bcm5411_driver); -} - -module_init(broadcom_init); -module_exit(broadcom_exit); - -static struct mdio_device_id __maybe_unused broadcom_tbl[] = { - { PHY_ID_BCM5411, 0xfffffff0 }, - { PHY_ID_BCM5421, 0xfffffff0 }, - { PHY_ID_BCM5461, 0xfffffff0 }, - { PHY_ID_BCM5464, 0xfffffff0 }, - { PHY_ID_BCM5482, 0xfffffff0 }, - { PHY_ID_BCM5482, 0xfffffff0 }, - { PHY_ID_BCM50610, 0xfffffff0 }, - { PHY_ID_BCM50610M, 0xfffffff0 }, - { PHY_ID_BCM57780, 0xfffffff0 }, - { PHY_ID_BCMAC131, 0xfffffff0 }, - { PHY_ID_BCM5241, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, broadcom_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/cicada.c b/ANDROID_3.4.5/drivers/net/phy/cicada.c deleted file mode 100644 index d2817316..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/cicada.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * drivers/net/phy/cicada.c - * - * Driver for Cicada PHYs - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -/* Cicada Extended Control Register 1 */ -#define MII_CIS8201_EXT_CON1 0x17 -#define MII_CIS8201_EXTCON1_INIT 0x0000 - -/* Cicada Interrupt Mask Register */ -#define MII_CIS8201_IMASK 0x19 -#define MII_CIS8201_IMASK_IEN 0x8000 -#define MII_CIS8201_IMASK_SPEED 0x4000 -#define MII_CIS8201_IMASK_LINK 0x2000 -#define MII_CIS8201_IMASK_DUPLEX 0x1000 -#define MII_CIS8201_IMASK_MASK 0xf000 - -/* Cicada Interrupt Status Register */ -#define MII_CIS8201_ISTAT 0x1a -#define MII_CIS8201_ISTAT_STATUS 0x8000 -#define MII_CIS8201_ISTAT_SPEED 0x4000 -#define MII_CIS8201_ISTAT_LINK 0x2000 -#define MII_CIS8201_ISTAT_DUPLEX 0x1000 - -/* Cicada Auxiliary Control/Status Register */ -#define MII_CIS8201_AUX_CONSTAT 0x1c -#define MII_CIS8201_AUXCONSTAT_INIT 0x0004 -#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020 -#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018 -#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010 -#define MII_CIS8201_AUXCONSTAT_100 0x0008 - -MODULE_DESCRIPTION("Cicadia PHY driver"); -MODULE_AUTHOR("Andy Fleming"); -MODULE_LICENSE("GPL"); - -static int cis820x_config_init(struct phy_device *phydev) -{ - int err; - - err = phy_write(phydev, MII_CIS8201_AUX_CONSTAT, - MII_CIS8201_AUXCONSTAT_INIT); - - if (err < 0) - return err; - - err = phy_write(phydev, MII_CIS8201_EXT_CON1, - MII_CIS8201_EXTCON1_INIT); - - return err; -} - -static int cis820x_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, MII_CIS8201_ISTAT); - - return (err < 0) ? err : 0; -} - -static int cis820x_config_intr(struct phy_device *phydev) -{ - int err; - - if(phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_CIS8201_IMASK, - MII_CIS8201_IMASK_MASK); - else - err = phy_write(phydev, MII_CIS8201_IMASK, 0); - - return err; -} - -/* Cicada 8201, a.k.a Vitesse VSC8201 */ -static struct phy_driver cis8201_driver = { - .phy_id = 0x000fc410, - .name = "Cicada Cis8201", - .phy_id_mask = 0x000ffff0, - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &cis820x_config_init, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &cis820x_ack_interrupt, - .config_intr = &cis820x_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -/* Cicada 8204 */ -static struct phy_driver cis8204_driver = { - .phy_id = 0x000fc440, - .name = "Cicada Cis8204", - .phy_id_mask = 0x000fffc0, - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &cis820x_config_init, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &cis820x_ack_interrupt, - .config_intr = &cis820x_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init cicada_init(void) -{ - int ret; - - ret = phy_driver_register(&cis8204_driver); - if (ret) - goto err1; - - ret = phy_driver_register(&cis8201_driver); - if (ret) - goto err2; - return 0; - -err2: - phy_driver_unregister(&cis8204_driver); -err1: - return ret; -} - -static void __exit cicada_exit(void) -{ - phy_driver_unregister(&cis8204_driver); - phy_driver_unregister(&cis8201_driver); -} - -module_init(cicada_init); -module_exit(cicada_exit); - -static struct mdio_device_id __maybe_unused cicada_tbl[] = { - { 0x000fc410, 0x000ffff0 }, - { 0x000fc440, 0x000fffc0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, cicada_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/davicom.c b/ANDROID_3.4.5/drivers/net/phy/davicom.c deleted file mode 100644 index 2f774acd..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/davicom.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * drivers/net/phy/davicom.c - * - * Driver for Davicom PHYs - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -#define MII_DM9161_SCR 0x10 -#define MII_DM9161_SCR_INIT 0x0610 -#define MII_DM9161_SCR_RMII 0x0100 - -/* DM9161 Interrupt Register */ -#define MII_DM9161_INTR 0x15 -#define MII_DM9161_INTR_PEND 0x8000 -#define MII_DM9161_INTR_DPLX_MASK 0x0800 -#define MII_DM9161_INTR_SPD_MASK 0x0400 -#define MII_DM9161_INTR_LINK_MASK 0x0200 -#define MII_DM9161_INTR_MASK 0x0100 -#define MII_DM9161_INTR_DPLX_CHANGE 0x0010 -#define MII_DM9161_INTR_SPD_CHANGE 0x0008 -#define MII_DM9161_INTR_LINK_CHANGE 0x0004 -#define MII_DM9161_INTR_INIT 0x0000 -#define MII_DM9161_INTR_STOP \ -(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \ - | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK) - -/* DM9161 10BT Configuration/Status */ -#define MII_DM9161_10BTCSR 0x12 -#define MII_DM9161_10BTCSR_INIT 0x7800 - -MODULE_DESCRIPTION("Davicom PHY driver"); -MODULE_AUTHOR("Andy Fleming"); -MODULE_LICENSE("GPL"); - - -#define DM9161_DELAY 1 -static int dm9161_config_intr(struct phy_device *phydev) -{ - int temp; - - temp = phy_read(phydev, MII_DM9161_INTR); - - if (temp < 0) - return temp; - - if(PHY_INTERRUPT_ENABLED == phydev->interrupts ) - temp &= ~(MII_DM9161_INTR_STOP); - else - temp |= MII_DM9161_INTR_STOP; - - temp = phy_write(phydev, MII_DM9161_INTR, temp); - - return temp; -} - -static int dm9161_config_aneg(struct phy_device *phydev) -{ - int err; - - /* Isolate the PHY */ - err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); - - if (err < 0) - return err; - - /* Configure the new settings */ - err = genphy_config_aneg(phydev); - - if (err < 0) - return err; - - return 0; -} - -static int dm9161_config_init(struct phy_device *phydev) -{ - int err, temp; - - /* Isolate the PHY */ - err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); - - if (err < 0) - return err; - - switch (phydev->interface) { - case PHY_INTERFACE_MODE_MII: - temp = MII_DM9161_SCR_INIT; - break; - case PHY_INTERFACE_MODE_RMII: - temp = MII_DM9161_SCR_INIT | MII_DM9161_SCR_RMII; - break; - default: - return -EINVAL; - } - - /* Do not bypass the scrambler/descrambler */ - err = phy_write(phydev, MII_DM9161_SCR, temp); - if (err < 0) - return err; - - /* Clear 10BTCSR to default */ - err = phy_write(phydev, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT); - - if (err < 0) - return err; - - /* Reconnect the PHY, and enable Autonegotiation */ - err = phy_write(phydev, MII_BMCR, BMCR_ANENABLE); - - if (err < 0) - return err; - - return 0; -} - -static int dm9161_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, MII_DM9161_INTR); - - return (err < 0) ? err : 0; -} - -static struct phy_driver dm9161e_driver = { - .phy_id = 0x0181b880, - .name = "Davicom DM9161E", - .phy_id_mask = 0x0ffffff0, - .features = PHY_BASIC_FEATURES, - .config_init = dm9161_config_init, - .config_aneg = dm9161_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver dm9161a_driver = { - .phy_id = 0x0181b8a0, - .name = "Davicom DM9161A", - .phy_id_mask = 0x0ffffff0, - .features = PHY_BASIC_FEATURES, - .config_init = dm9161_config_init, - .config_aneg = dm9161_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver dm9131_driver = { - .phy_id = 0x00181b80, - .name = "Davicom DM9131", - .phy_id_mask = 0x0ffffff0, - .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = dm9161_ack_interrupt, - .config_intr = dm9161_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init davicom_init(void) -{ - int ret; - - ret = phy_driver_register(&dm9161e_driver); - if (ret) - goto err1; - - ret = phy_driver_register(&dm9161a_driver); - if (ret) - goto err2; - - ret = phy_driver_register(&dm9131_driver); - if (ret) - goto err3; - return 0; - - err3: - phy_driver_unregister(&dm9161a_driver); - err2: - phy_driver_unregister(&dm9161e_driver); - err1: - return ret; -} - -static void __exit davicom_exit(void) -{ - phy_driver_unregister(&dm9161e_driver); - phy_driver_unregister(&dm9161a_driver); - phy_driver_unregister(&dm9131_driver); -} - -module_init(davicom_init); -module_exit(davicom_exit); - -static struct mdio_device_id __maybe_unused davicom_tbl[] = { - { 0x0181b880, 0x0ffffff0 }, - { 0x0181b8a0, 0x0ffffff0 }, - { 0x00181b80, 0x0ffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, davicom_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/dp83640.c b/ANDROID_3.4.5/drivers/net/phy/dp83640.c deleted file mode 100644 index dd7ae195..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/dp83640.c +++ /dev/null @@ -1,1257 +0,0 @@ -/* - * Driver for the National Semiconductor DP83640 PHYTER - * - * Copyright (C) 2010 OMICRON electronics GmbH - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <linux/ethtool.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/mii.h> -#include <linux/module.h> -#include <linux/net_tstamp.h> -#include <linux/netdevice.h> -#include <linux/phy.h> -#include <linux/ptp_classify.h> -#include <linux/ptp_clock_kernel.h> - -#include "dp83640_reg.h" - -#define DP83640_PHY_ID 0x20005ce1 -#define PAGESEL 0x13 -#define LAYER4 0x02 -#define LAYER2 0x01 -#define MAX_RXTS 64 -#define N_EXT_TS 6 -#define PSF_PTPVER 2 -#define PSF_EVNT 0x4000 -#define PSF_RX 0x2000 -#define PSF_TX 0x1000 -#define EXT_EVENT 1 -#define CAL_EVENT 7 -#define CAL_TRIGGER 7 -#define PER_TRIGGER 6 - -/* phyter seems to miss the mark by 16 ns */ -#define ADJTIME_FIX 16 - -#if defined(__BIG_ENDIAN) -#define ENDIAN_FLAG 0 -#elif defined(__LITTLE_ENDIAN) -#define ENDIAN_FLAG PSF_ENDIAN -#endif - -#define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb)) - -struct phy_rxts { - u16 ns_lo; /* ns[15:0] */ - u16 ns_hi; /* overflow[1:0], ns[29:16] */ - u16 sec_lo; /* sec[15:0] */ - u16 sec_hi; /* sec[31:16] */ - u16 seqid; /* sequenceId[15:0] */ - u16 msgtype; /* messageType[3:0], hash[11:0] */ -}; - -struct phy_txts { - u16 ns_lo; /* ns[15:0] */ - u16 ns_hi; /* overflow[1:0], ns[29:16] */ - u16 sec_lo; /* sec[15:0] */ - u16 sec_hi; /* sec[31:16] */ -}; - -struct rxts { - struct list_head list; - unsigned long tmo; - u64 ns; - u16 seqid; - u8 msgtype; - u16 hash; -}; - -struct dp83640_clock; - -struct dp83640_private { - struct list_head list; - struct dp83640_clock *clock; - struct phy_device *phydev; - struct work_struct ts_work; - int hwts_tx_en; - int hwts_rx_en; - int layer; - int version; - /* remember state of cfg0 during calibration */ - int cfg0; - /* remember the last event time stamp */ - struct phy_txts edata; - /* list of rx timestamps */ - struct list_head rxts; - struct list_head rxpool; - struct rxts rx_pool_data[MAX_RXTS]; - /* protects above three fields from concurrent access */ - spinlock_t rx_lock; - /* queues of incoming and outgoing packets */ - struct sk_buff_head rx_queue; - struct sk_buff_head tx_queue; -}; - -struct dp83640_clock { - /* keeps the instance in the 'phyter_clocks' list */ - struct list_head list; - /* we create one clock instance per MII bus */ - struct mii_bus *bus; - /* protects extended registers from concurrent access */ - struct mutex extreg_lock; - /* remembers which page was last selected */ - int page; - /* our advertised capabilities */ - struct ptp_clock_info caps; - /* protects the three fields below from concurrent access */ - struct mutex clock_lock; - /* the one phyter from which we shall read */ - struct dp83640_private *chosen; - /* list of the other attached phyters, not chosen */ - struct list_head phylist; - /* reference to our PTP hardware clock */ - struct ptp_clock *ptp_clock; -}; - -/* globals */ - -enum { - CALIBRATE_GPIO, - PEROUT_GPIO, - EXTTS0_GPIO, - EXTTS1_GPIO, - EXTTS2_GPIO, - EXTTS3_GPIO, - EXTTS4_GPIO, - EXTTS5_GPIO, - GPIO_TABLE_SIZE -}; - -static int chosen_phy = -1; -static ushort gpio_tab[GPIO_TABLE_SIZE] = { - 1, 2, 3, 4, 8, 9, 10, 11 -}; - -module_param(chosen_phy, int, 0444); -module_param_array(gpio_tab, ushort, NULL, 0444); - -MODULE_PARM_DESC(chosen_phy, \ - "The address of the PHY to use for the ancillary clock features"); -MODULE_PARM_DESC(gpio_tab, \ - "Which GPIO line to use for which purpose: cal,perout,extts1,...,extts6"); - -/* a list of clocks and a mutex to protect it */ -static LIST_HEAD(phyter_clocks); -static DEFINE_MUTEX(phyter_clocks_lock); - -static void rx_timestamp_work(struct work_struct *work); - -/* extended register access functions */ - -#define BROADCAST_ADDR 31 - -static inline int broadcast_write(struct mii_bus *bus, u32 regnum, u16 val) -{ - return mdiobus_write(bus, BROADCAST_ADDR, regnum, val); -} - -/* Caller must hold extreg_lock. */ -static int ext_read(struct phy_device *phydev, int page, u32 regnum) -{ - struct dp83640_private *dp83640 = phydev->priv; - int val; - - if (dp83640->clock->page != page) { - broadcast_write(phydev->bus, PAGESEL, page); - dp83640->clock->page = page; - } - val = phy_read(phydev, regnum); - - return val; -} - -/* Caller must hold extreg_lock. */ -static void ext_write(int broadcast, struct phy_device *phydev, - int page, u32 regnum, u16 val) -{ - struct dp83640_private *dp83640 = phydev->priv; - - if (dp83640->clock->page != page) { - broadcast_write(phydev->bus, PAGESEL, page); - dp83640->clock->page = page; - } - if (broadcast) - broadcast_write(phydev->bus, regnum, val); - else - phy_write(phydev, regnum, val); -} - -/* Caller must hold extreg_lock. */ -static int tdr_write(int bc, struct phy_device *dev, - const struct timespec *ts, u16 cmd) -{ - ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_nsec & 0xffff);/* ns[15:0] */ - ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_nsec >> 16); /* ns[31:16] */ - ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_sec & 0xffff); /* sec[15:0] */ - ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_sec >> 16); /* sec[31:16]*/ - - ext_write(bc, dev, PAGE4, PTP_CTL, cmd); - - return 0; -} - -/* convert phy timestamps into driver timestamps */ - -static void phy2rxts(struct phy_rxts *p, struct rxts *rxts) -{ - u32 sec; - - sec = p->sec_lo; - sec |= p->sec_hi << 16; - - rxts->ns = p->ns_lo; - rxts->ns |= (p->ns_hi & 0x3fff) << 16; - rxts->ns += ((u64)sec) * 1000000000ULL; - rxts->seqid = p->seqid; - rxts->msgtype = (p->msgtype >> 12) & 0xf; - rxts->hash = p->msgtype & 0x0fff; - rxts->tmo = jiffies + 2; -} - -static u64 phy2txts(struct phy_txts *p) -{ - u64 ns; - u32 sec; - - sec = p->sec_lo; - sec |= p->sec_hi << 16; - - ns = p->ns_lo; - ns |= (p->ns_hi & 0x3fff) << 16; - ns += ((u64)sec) * 1000000000ULL; - - return ns; -} - -static void periodic_output(struct dp83640_clock *clock, - struct ptp_clock_request *clkreq, bool on) -{ - struct dp83640_private *dp83640 = clock->chosen; - struct phy_device *phydev = dp83640->phydev; - u32 sec, nsec, period; - u16 gpio, ptp_trig, trigger, val; - - gpio = on ? gpio_tab[PEROUT_GPIO] : 0; - trigger = PER_TRIGGER; - - ptp_trig = TRIG_WR | - (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT | - (gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT | - TRIG_PER | - TRIG_PULSE; - - val = (trigger & TRIG_SEL_MASK) << TRIG_SEL_SHIFT; - - if (!on) { - val |= TRIG_DIS; - mutex_lock(&clock->extreg_lock); - ext_write(0, phydev, PAGE5, PTP_TRIG, ptp_trig); - ext_write(0, phydev, PAGE4, PTP_CTL, val); - mutex_unlock(&clock->extreg_lock); - return; - } - - sec = clkreq->perout.start.sec; - nsec = clkreq->perout.start.nsec; - period = clkreq->perout.period.sec * 1000000000UL; - period += clkreq->perout.period.nsec; - - mutex_lock(&clock->extreg_lock); - - ext_write(0, phydev, PAGE5, PTP_TRIG, ptp_trig); - - /*load trigger*/ - val |= TRIG_LOAD; - ext_write(0, phydev, PAGE4, PTP_CTL, val); - ext_write(0, phydev, PAGE4, PTP_TDR, nsec & 0xffff); /* ns[15:0] */ - ext_write(0, phydev, PAGE4, PTP_TDR, nsec >> 16); /* ns[31:16] */ - ext_write(0, phydev, PAGE4, PTP_TDR, sec & 0xffff); /* sec[15:0] */ - ext_write(0, phydev, PAGE4, PTP_TDR, sec >> 16); /* sec[31:16] */ - ext_write(0, phydev, PAGE4, PTP_TDR, period & 0xffff); /* ns[15:0] */ - ext_write(0, phydev, PAGE4, PTP_TDR, period >> 16); /* ns[31:16] */ - - /*enable trigger*/ - val &= ~TRIG_LOAD; - val |= TRIG_EN; - ext_write(0, phydev, PAGE4, PTP_CTL, val); - - mutex_unlock(&clock->extreg_lock); -} - -/* ptp clock methods */ - -static int ptp_dp83640_adjfreq(struct ptp_clock_info *ptp, s32 ppb) -{ - struct dp83640_clock *clock = - container_of(ptp, struct dp83640_clock, caps); - struct phy_device *phydev = clock->chosen->phydev; - u64 rate; - int neg_adj = 0; - u16 hi, lo; - - if (ppb < 0) { - neg_adj = 1; - ppb = -ppb; - } - rate = ppb; - rate <<= 26; - rate = div_u64(rate, 1953125); - - hi = (rate >> 16) & PTP_RATE_HI_MASK; - if (neg_adj) - hi |= PTP_RATE_DIR; - - lo = rate & 0xffff; - - mutex_lock(&clock->extreg_lock); - - ext_write(1, phydev, PAGE4, PTP_RATEH, hi); - ext_write(1, phydev, PAGE4, PTP_RATEL, lo); - - mutex_unlock(&clock->extreg_lock); - - return 0; -} - -static int ptp_dp83640_adjtime(struct ptp_clock_info *ptp, s64 delta) -{ - struct dp83640_clock *clock = - container_of(ptp, struct dp83640_clock, caps); - struct phy_device *phydev = clock->chosen->phydev; - struct timespec ts; - int err; - - delta += ADJTIME_FIX; - - ts = ns_to_timespec(delta); - - mutex_lock(&clock->extreg_lock); - - err = tdr_write(1, phydev, &ts, PTP_STEP_CLK); - - mutex_unlock(&clock->extreg_lock); - - return err; -} - -static int ptp_dp83640_gettime(struct ptp_clock_info *ptp, struct timespec *ts) -{ - struct dp83640_clock *clock = - container_of(ptp, struct dp83640_clock, caps); - struct phy_device *phydev = clock->chosen->phydev; - unsigned int val[4]; - - mutex_lock(&clock->extreg_lock); - - ext_write(0, phydev, PAGE4, PTP_CTL, PTP_RD_CLK); - - val[0] = ext_read(phydev, PAGE4, PTP_TDR); /* ns[15:0] */ - val[1] = ext_read(phydev, PAGE4, PTP_TDR); /* ns[31:16] */ - val[2] = ext_read(phydev, PAGE4, PTP_TDR); /* sec[15:0] */ - val[3] = ext_read(phydev, PAGE4, PTP_TDR); /* sec[31:16] */ - - mutex_unlock(&clock->extreg_lock); - - ts->tv_nsec = val[0] | (val[1] << 16); - ts->tv_sec = val[2] | (val[3] << 16); - - return 0; -} - -static int ptp_dp83640_settime(struct ptp_clock_info *ptp, - const struct timespec *ts) -{ - struct dp83640_clock *clock = - container_of(ptp, struct dp83640_clock, caps); - struct phy_device *phydev = clock->chosen->phydev; - int err; - - mutex_lock(&clock->extreg_lock); - - err = tdr_write(1, phydev, ts, PTP_LOAD_CLK); - - mutex_unlock(&clock->extreg_lock); - - return err; -} - -static int ptp_dp83640_enable(struct ptp_clock_info *ptp, - struct ptp_clock_request *rq, int on) -{ - struct dp83640_clock *clock = - container_of(ptp, struct dp83640_clock, caps); - struct phy_device *phydev = clock->chosen->phydev; - int index; - u16 evnt, event_num, gpio_num; - - switch (rq->type) { - case PTP_CLK_REQ_EXTTS: - index = rq->extts.index; - if (index < 0 || index >= N_EXT_TS) - return -EINVAL; - event_num = EXT_EVENT + index; - evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT; - if (on) { - gpio_num = gpio_tab[EXTTS0_GPIO + index]; - evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; - evnt |= EVNT_RISE; - } - ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); - return 0; - - case PTP_CLK_REQ_PEROUT: - if (rq->perout.index != 0) - return -EINVAL; - periodic_output(clock, rq, on); - return 0; - - default: - break; - } - - return -EOPNOTSUPP; -} - -static u8 status_frame_dst[6] = { 0x01, 0x1B, 0x19, 0x00, 0x00, 0x00 }; -static u8 status_frame_src[6] = { 0x08, 0x00, 0x17, 0x0B, 0x6B, 0x0F }; - -static void enable_status_frames(struct phy_device *phydev, bool on) -{ - u16 cfg0 = 0, ver; - - if (on) - cfg0 = PSF_EVNT_EN | PSF_RXTS_EN | PSF_TXTS_EN | ENDIAN_FLAG; - - ver = (PSF_PTPVER & VERSIONPTP_MASK) << VERSIONPTP_SHIFT; - - ext_write(0, phydev, PAGE5, PSF_CFG0, cfg0); - ext_write(0, phydev, PAGE6, PSF_CFG1, ver); - - if (!phydev->attached_dev) { - pr_warning("dp83640: expected to find an attached netdevice\n"); - return; - } - - if (on) { - if (dev_mc_add(phydev->attached_dev, status_frame_dst)) - pr_warning("dp83640: failed to add mc address\n"); - } else { - if (dev_mc_del(phydev->attached_dev, status_frame_dst)) - pr_warning("dp83640: failed to delete mc address\n"); - } -} - -static bool is_status_frame(struct sk_buff *skb, int type) -{ - struct ethhdr *h = eth_hdr(skb); - - if (PTP_CLASS_V2_L2 == type && - !memcmp(h->h_source, status_frame_src, sizeof(status_frame_src))) - return true; - else - return false; -} - -static int expired(struct rxts *rxts) -{ - return time_after(jiffies, rxts->tmo); -} - -/* Caller must hold rx_lock. */ -static void prune_rx_ts(struct dp83640_private *dp83640) -{ - struct list_head *this, *next; - struct rxts *rxts; - - list_for_each_safe(this, next, &dp83640->rxts) { - rxts = list_entry(this, struct rxts, list); - if (expired(rxts)) { - list_del_init(&rxts->list); - list_add(&rxts->list, &dp83640->rxpool); - } - } -} - -/* synchronize the phyters so they act as one clock */ - -static void enable_broadcast(struct phy_device *phydev, int init_page, int on) -{ - int val; - phy_write(phydev, PAGESEL, 0); - val = phy_read(phydev, PHYCR2); - if (on) - val |= BC_WRITE; - else - val &= ~BC_WRITE; - phy_write(phydev, PHYCR2, val); - phy_write(phydev, PAGESEL, init_page); -} - -static void recalibrate(struct dp83640_clock *clock) -{ - s64 now, diff; - struct phy_txts event_ts; - struct timespec ts; - struct list_head *this; - struct dp83640_private *tmp; - struct phy_device *master = clock->chosen->phydev; - u16 cal_gpio, cfg0, evnt, ptp_trig, trigger, val; - - trigger = CAL_TRIGGER; - cal_gpio = gpio_tab[CALIBRATE_GPIO]; - - mutex_lock(&clock->extreg_lock); - - /* - * enable broadcast, disable status frames, enable ptp clock - */ - list_for_each(this, &clock->phylist) { - tmp = list_entry(this, struct dp83640_private, list); - enable_broadcast(tmp->phydev, clock->page, 1); - tmp->cfg0 = ext_read(tmp->phydev, PAGE5, PSF_CFG0); - ext_write(0, tmp->phydev, PAGE5, PSF_CFG0, 0); - ext_write(0, tmp->phydev, PAGE4, PTP_CTL, PTP_ENABLE); - } - enable_broadcast(master, clock->page, 1); - cfg0 = ext_read(master, PAGE5, PSF_CFG0); - ext_write(0, master, PAGE5, PSF_CFG0, 0); - ext_write(0, master, PAGE4, PTP_CTL, PTP_ENABLE); - - /* - * enable an event timestamp - */ - evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE; - evnt |= (CAL_EVENT & EVNT_SEL_MASK) << EVNT_SEL_SHIFT; - evnt |= (cal_gpio & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; - - list_for_each(this, &clock->phylist) { - tmp = list_entry(this, struct dp83640_private, list); - ext_write(0, tmp->phydev, PAGE5, PTP_EVNT, evnt); - } - ext_write(0, master, PAGE5, PTP_EVNT, evnt); - - /* - * configure a trigger - */ - ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE; - ptp_trig |= (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT; - ptp_trig |= (cal_gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT; - ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig); - - /* load trigger */ - val = (trigger & TRIG_SEL_MASK) << TRIG_SEL_SHIFT; - val |= TRIG_LOAD; - ext_write(0, master, PAGE4, PTP_CTL, val); - - /* enable trigger */ - val &= ~TRIG_LOAD; - val |= TRIG_EN; - ext_write(0, master, PAGE4, PTP_CTL, val); - - /* disable trigger */ - val = (trigger & TRIG_SEL_MASK) << TRIG_SEL_SHIFT; - val |= TRIG_DIS; - ext_write(0, master, PAGE4, PTP_CTL, val); - - /* - * read out and correct offsets - */ - val = ext_read(master, PAGE4, PTP_STS); - pr_info("master PTP_STS 0x%04hx", val); - val = ext_read(master, PAGE4, PTP_ESTS); - pr_info("master PTP_ESTS 0x%04hx", val); - event_ts.ns_lo = ext_read(master, PAGE4, PTP_EDATA); - event_ts.ns_hi = ext_read(master, PAGE4, PTP_EDATA); - event_ts.sec_lo = ext_read(master, PAGE4, PTP_EDATA); - event_ts.sec_hi = ext_read(master, PAGE4, PTP_EDATA); - now = phy2txts(&event_ts); - - list_for_each(this, &clock->phylist) { - tmp = list_entry(this, struct dp83640_private, list); - val = ext_read(tmp->phydev, PAGE4, PTP_STS); - pr_info("slave PTP_STS 0x%04hx", val); - val = ext_read(tmp->phydev, PAGE4, PTP_ESTS); - pr_info("slave PTP_ESTS 0x%04hx", val); - event_ts.ns_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); - event_ts.ns_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA); - event_ts.sec_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); - event_ts.sec_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA); - diff = now - (s64) phy2txts(&event_ts); - pr_info("slave offset %lld nanoseconds\n", diff); - diff += ADJTIME_FIX; - ts = ns_to_timespec(diff); - tdr_write(0, tmp->phydev, &ts, PTP_STEP_CLK); - } - - /* - * restore status frames - */ - list_for_each(this, &clock->phylist) { - tmp = list_entry(this, struct dp83640_private, list); - ext_write(0, tmp->phydev, PAGE5, PSF_CFG0, tmp->cfg0); - } - ext_write(0, master, PAGE5, PSF_CFG0, cfg0); - - mutex_unlock(&clock->extreg_lock); -} - -/* time stamping methods */ - -static inline u16 exts_chan_to_edata(int ch) -{ - return 1 << ((ch + EXT_EVENT) * 2); -} - -static int decode_evnt(struct dp83640_private *dp83640, - void *data, u16 ests) -{ - struct phy_txts *phy_txts; - struct ptp_clock_event event; - int i, parsed; - int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK; - u16 ext_status = 0; - - if (ests & MULT_EVNT) { - ext_status = *(u16 *) data; - data += sizeof(ext_status); - } - - phy_txts = data; - - switch (words) { /* fall through in every case */ - case 3: - dp83640->edata.sec_hi = phy_txts->sec_hi; - case 2: - dp83640->edata.sec_lo = phy_txts->sec_lo; - case 1: - dp83640->edata.ns_hi = phy_txts->ns_hi; - case 0: - dp83640->edata.ns_lo = phy_txts->ns_lo; - } - - if (ext_status) { - parsed = words + 2; - } else { - parsed = words + 1; - i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK) - EXT_EVENT; - ext_status = exts_chan_to_edata(i); - } - - event.type = PTP_CLOCK_EXTTS; - event.timestamp = phy2txts(&dp83640->edata); - - for (i = 0; i < N_EXT_TS; i++) { - if (ext_status & exts_chan_to_edata(i)) { - event.index = i; - ptp_clock_event(dp83640->clock->ptp_clock, &event); - } - } - - return parsed * sizeof(u16); -} - -static void decode_rxts(struct dp83640_private *dp83640, - struct phy_rxts *phy_rxts) -{ - struct rxts *rxts; - unsigned long flags; - - spin_lock_irqsave(&dp83640->rx_lock, flags); - - prune_rx_ts(dp83640); - - if (list_empty(&dp83640->rxpool)) { - pr_debug("dp83640: rx timestamp pool is empty\n"); - goto out; - } - rxts = list_first_entry(&dp83640->rxpool, struct rxts, list); - list_del_init(&rxts->list); - phy2rxts(phy_rxts, rxts); - list_add_tail(&rxts->list, &dp83640->rxts); -out: - spin_unlock_irqrestore(&dp83640->rx_lock, flags); -} - -static void decode_txts(struct dp83640_private *dp83640, - struct phy_txts *phy_txts) -{ - struct skb_shared_hwtstamps shhwtstamps; - struct sk_buff *skb; - u64 ns; - - /* We must already have the skb that triggered this. */ - - skb = skb_dequeue(&dp83640->tx_queue); - - if (!skb) { - pr_debug("dp83640: have timestamp but tx_queue empty\n"); - return; - } - ns = phy2txts(phy_txts); - memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - shhwtstamps.hwtstamp = ns_to_ktime(ns); - skb_complete_tx_timestamp(skb, &shhwtstamps); -} - -static void decode_status_frame(struct dp83640_private *dp83640, - struct sk_buff *skb) -{ - struct phy_rxts *phy_rxts; - struct phy_txts *phy_txts; - u8 *ptr; - int len, size; - u16 ests, type; - - ptr = skb->data + 2; - - for (len = skb_headlen(skb) - 2; len > sizeof(type); len -= size) { - - type = *(u16 *)ptr; - ests = type & 0x0fff; - type = type & 0xf000; - len -= sizeof(type); - ptr += sizeof(type); - - if (PSF_RX == type && len >= sizeof(*phy_rxts)) { - - phy_rxts = (struct phy_rxts *) ptr; - decode_rxts(dp83640, phy_rxts); - size = sizeof(*phy_rxts); - - } else if (PSF_TX == type && len >= sizeof(*phy_txts)) { - - phy_txts = (struct phy_txts *) ptr; - decode_txts(dp83640, phy_txts); - size = sizeof(*phy_txts); - - } else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) { - - size = decode_evnt(dp83640, ptr, ests); - - } else { - size = 0; - break; - } - ptr += size; - } -} - -static int is_sync(struct sk_buff *skb, int type) -{ - u8 *data = skb->data, *msgtype; - unsigned int offset = 0; - - switch (type) { - case PTP_CLASS_V1_IPV4: - case PTP_CLASS_V2_IPV4: - offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; - break; - case PTP_CLASS_V1_IPV6: - case PTP_CLASS_V2_IPV6: - offset = OFF_PTP6; - break; - case PTP_CLASS_V2_L2: - offset = ETH_HLEN; - break; - case PTP_CLASS_V2_VLAN: - offset = ETH_HLEN + VLAN_HLEN; - break; - default: - return 0; - } - - if (type & PTP_CLASS_V1) - offset += OFF_PTP_CONTROL; - - if (skb->len < offset + 1) - return 0; - - msgtype = data + offset; - - return (*msgtype & 0xf) == 0; -} - -static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts) -{ - u16 *seqid; - unsigned int offset; - u8 *msgtype, *data = skb_mac_header(skb); - - /* check sequenceID, messageType, 12 bit hash of offset 20-29 */ - - switch (type) { - case PTP_CLASS_V1_IPV4: - case PTP_CLASS_V2_IPV4: - offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; - break; - case PTP_CLASS_V1_IPV6: - case PTP_CLASS_V2_IPV6: - offset = OFF_PTP6; - break; - case PTP_CLASS_V2_L2: - offset = ETH_HLEN; - break; - case PTP_CLASS_V2_VLAN: - offset = ETH_HLEN + VLAN_HLEN; - break; - default: - return 0; - } - - if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid)) - return 0; - - if (unlikely(type & PTP_CLASS_V1)) - msgtype = data + offset + OFF_PTP_CONTROL; - else - msgtype = data + offset; - - seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID); - - return (rxts->msgtype == (*msgtype & 0xf) && - rxts->seqid == ntohs(*seqid)); -} - -static void dp83640_free_clocks(void) -{ - struct dp83640_clock *clock; - struct list_head *this, *next; - - mutex_lock(&phyter_clocks_lock); - - list_for_each_safe(this, next, &phyter_clocks) { - clock = list_entry(this, struct dp83640_clock, list); - if (!list_empty(&clock->phylist)) { - pr_warning("phy list non-empty while unloading"); - BUG(); - } - list_del(&clock->list); - mutex_destroy(&clock->extreg_lock); - mutex_destroy(&clock->clock_lock); - put_device(&clock->bus->dev); - kfree(clock); - } - - mutex_unlock(&phyter_clocks_lock); -} - -static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus) -{ - INIT_LIST_HEAD(&clock->list); - clock->bus = bus; - mutex_init(&clock->extreg_lock); - mutex_init(&clock->clock_lock); - INIT_LIST_HEAD(&clock->phylist); - clock->caps.owner = THIS_MODULE; - sprintf(clock->caps.name, "dp83640 timer"); - clock->caps.max_adj = 1953124; - clock->caps.n_alarm = 0; - clock->caps.n_ext_ts = N_EXT_TS; - clock->caps.n_per_out = 1; - clock->caps.pps = 0; - clock->caps.adjfreq = ptp_dp83640_adjfreq; - clock->caps.adjtime = ptp_dp83640_adjtime; - clock->caps.gettime = ptp_dp83640_gettime; - clock->caps.settime = ptp_dp83640_settime; - clock->caps.enable = ptp_dp83640_enable; - /* - * Get a reference to this bus instance. - */ - get_device(&bus->dev); -} - -static int choose_this_phy(struct dp83640_clock *clock, - struct phy_device *phydev) -{ - if (chosen_phy == -1 && !clock->chosen) - return 1; - - if (chosen_phy == phydev->addr) - return 1; - - return 0; -} - -static struct dp83640_clock *dp83640_clock_get(struct dp83640_clock *clock) -{ - if (clock) - mutex_lock(&clock->clock_lock); - return clock; -} - -/* - * Look up and lock a clock by bus instance. - * If there is no clock for this bus, then create it first. - */ -static struct dp83640_clock *dp83640_clock_get_bus(struct mii_bus *bus) -{ - struct dp83640_clock *clock = NULL, *tmp; - struct list_head *this; - - mutex_lock(&phyter_clocks_lock); - - list_for_each(this, &phyter_clocks) { - tmp = list_entry(this, struct dp83640_clock, list); - if (tmp->bus == bus) { - clock = tmp; - break; - } - } - if (clock) - goto out; - - clock = kzalloc(sizeof(struct dp83640_clock), GFP_KERNEL); - if (!clock) - goto out; - - dp83640_clock_init(clock, bus); - list_add_tail(&phyter_clocks, &clock->list); -out: - mutex_unlock(&phyter_clocks_lock); - - return dp83640_clock_get(clock); -} - -static void dp83640_clock_put(struct dp83640_clock *clock) -{ - mutex_unlock(&clock->clock_lock); -} - -static int dp83640_probe(struct phy_device *phydev) -{ - struct dp83640_clock *clock; - struct dp83640_private *dp83640; - int err = -ENOMEM, i; - - if (phydev->addr == BROADCAST_ADDR) - return 0; - - clock = dp83640_clock_get_bus(phydev->bus); - if (!clock) - goto no_clock; - - dp83640 = kzalloc(sizeof(struct dp83640_private), GFP_KERNEL); - if (!dp83640) - goto no_memory; - - dp83640->phydev = phydev; - INIT_WORK(&dp83640->ts_work, rx_timestamp_work); - - INIT_LIST_HEAD(&dp83640->rxts); - INIT_LIST_HEAD(&dp83640->rxpool); - for (i = 0; i < MAX_RXTS; i++) - list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool); - - phydev->priv = dp83640; - - spin_lock_init(&dp83640->rx_lock); - skb_queue_head_init(&dp83640->rx_queue); - skb_queue_head_init(&dp83640->tx_queue); - - dp83640->clock = clock; - - if (choose_this_phy(clock, phydev)) { - clock->chosen = dp83640; - clock->ptp_clock = ptp_clock_register(&clock->caps); - if (IS_ERR(clock->ptp_clock)) { - err = PTR_ERR(clock->ptp_clock); - goto no_register; - } - } else - list_add_tail(&dp83640->list, &clock->phylist); - - if (clock->chosen && !list_empty(&clock->phylist)) - recalibrate(clock); - else - enable_broadcast(dp83640->phydev, clock->page, 1); - - dp83640_clock_put(clock); - return 0; - -no_register: - clock->chosen = NULL; - kfree(dp83640); -no_memory: - dp83640_clock_put(clock); -no_clock: - return err; -} - -static void dp83640_remove(struct phy_device *phydev) -{ - struct dp83640_clock *clock; - struct list_head *this, *next; - struct dp83640_private *tmp, *dp83640 = phydev->priv; - struct sk_buff *skb; - - if (phydev->addr == BROADCAST_ADDR) - return; - - enable_status_frames(phydev, false); - cancel_work_sync(&dp83640->ts_work); - - while ((skb = skb_dequeue(&dp83640->rx_queue)) != NULL) - kfree_skb(skb); - - while ((skb = skb_dequeue(&dp83640->tx_queue)) != NULL) - skb_complete_tx_timestamp(skb, NULL); - - clock = dp83640_clock_get(dp83640->clock); - - if (dp83640 == clock->chosen) { - ptp_clock_unregister(clock->ptp_clock); - clock->chosen = NULL; - } else { - list_for_each_safe(this, next, &clock->phylist) { - tmp = list_entry(this, struct dp83640_private, list); - if (tmp == dp83640) { - list_del_init(&tmp->list); - break; - } - } - } - - dp83640_clock_put(clock); - kfree(dp83640); -} - -static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) -{ - struct dp83640_private *dp83640 = phydev->priv; - struct hwtstamp_config cfg; - u16 txcfg0, rxcfg0; - - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) - return -EFAULT; - - if (cfg.flags) /* reserved for future extensions */ - return -EINVAL; - - if (cfg.tx_type < 0 || cfg.tx_type > HWTSTAMP_TX_ONESTEP_SYNC) - return -ERANGE; - - dp83640->hwts_tx_en = cfg.tx_type; - - switch (cfg.rx_filter) { - case HWTSTAMP_FILTER_NONE: - dp83640->hwts_rx_en = 0; - dp83640->layer = 0; - dp83640->version = 0; - break; - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - dp83640->hwts_rx_en = 1; - dp83640->layer = LAYER4; - dp83640->version = 1; - break; - case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: - dp83640->hwts_rx_en = 1; - dp83640->layer = LAYER4; - dp83640->version = 2; - break; - case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: - dp83640->hwts_rx_en = 1; - dp83640->layer = LAYER2; - dp83640->version = 2; - break; - case HWTSTAMP_FILTER_PTP_V2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: - dp83640->hwts_rx_en = 1; - dp83640->layer = LAYER4|LAYER2; - dp83640->version = 2; - break; - default: - return -ERANGE; - } - - txcfg0 = (dp83640->version & TX_PTP_VER_MASK) << TX_PTP_VER_SHIFT; - rxcfg0 = (dp83640->version & TX_PTP_VER_MASK) << TX_PTP_VER_SHIFT; - - if (dp83640->layer & LAYER2) { - txcfg0 |= TX_L2_EN; - rxcfg0 |= RX_L2_EN; - } - if (dp83640->layer & LAYER4) { - txcfg0 |= TX_IPV6_EN | TX_IPV4_EN; - rxcfg0 |= RX_IPV6_EN | RX_IPV4_EN; - } - - if (dp83640->hwts_tx_en) - txcfg0 |= TX_TS_EN; - - if (dp83640->hwts_tx_en == HWTSTAMP_TX_ONESTEP_SYNC) - txcfg0 |= SYNC_1STEP | CHK_1STEP; - - if (dp83640->hwts_rx_en) - rxcfg0 |= RX_TS_EN; - - mutex_lock(&dp83640->clock->extreg_lock); - - if (dp83640->hwts_tx_en || dp83640->hwts_rx_en) { - enable_status_frames(phydev, true); - ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); - } - - ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); - ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); - - mutex_unlock(&dp83640->clock->extreg_lock); - - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; -} - -static void rx_timestamp_work(struct work_struct *work) -{ - struct dp83640_private *dp83640 = - container_of(work, struct dp83640_private, ts_work); - struct list_head *this, *next; - struct rxts *rxts; - struct skb_shared_hwtstamps *shhwtstamps; - struct sk_buff *skb; - unsigned int type; - unsigned long flags; - - /* Deliver each deferred packet, with or without a time stamp. */ - - while ((skb = skb_dequeue(&dp83640->rx_queue)) != NULL) { - type = SKB_PTP_TYPE(skb); - spin_lock_irqsave(&dp83640->rx_lock, flags); - list_for_each_safe(this, next, &dp83640->rxts) { - rxts = list_entry(this, struct rxts, list); - if (match(skb, type, rxts)) { - shhwtstamps = skb_hwtstamps(skb); - memset(shhwtstamps, 0, sizeof(*shhwtstamps)); - shhwtstamps->hwtstamp = ns_to_ktime(rxts->ns); - list_del_init(&rxts->list); - list_add(&rxts->list, &dp83640->rxpool); - break; - } - } - spin_unlock_irqrestore(&dp83640->rx_lock, flags); - netif_rx_ni(skb); - } - - /* Clear out expired time stamps. */ - - spin_lock_irqsave(&dp83640->rx_lock, flags); - prune_rx_ts(dp83640); - spin_unlock_irqrestore(&dp83640->rx_lock, flags); -} - -static bool dp83640_rxtstamp(struct phy_device *phydev, - struct sk_buff *skb, int type) -{ - struct dp83640_private *dp83640 = phydev->priv; - - if (!dp83640->hwts_rx_en) - return false; - - if (is_status_frame(skb, type)) { - decode_status_frame(dp83640, skb); - kfree_skb(skb); - return true; - } - - SKB_PTP_TYPE(skb) = type; - skb_queue_tail(&dp83640->rx_queue, skb); - schedule_work(&dp83640->ts_work); - - return true; -} - -static void dp83640_txtstamp(struct phy_device *phydev, - struct sk_buff *skb, int type) -{ - struct dp83640_private *dp83640 = phydev->priv; - - switch (dp83640->hwts_tx_en) { - - case HWTSTAMP_TX_ONESTEP_SYNC: - if (is_sync(skb, type)) { - skb_complete_tx_timestamp(skb, NULL); - return; - } - /* fall through */ - case HWTSTAMP_TX_ON: - skb_queue_tail(&dp83640->tx_queue, skb); - schedule_work(&dp83640->ts_work); - break; - - case HWTSTAMP_TX_OFF: - default: - skb_complete_tx_timestamp(skb, NULL); - break; - } -} - -static struct phy_driver dp83640_driver = { - .phy_id = DP83640_PHY_ID, - .phy_id_mask = 0xfffffff0, - .name = "NatSemi DP83640", - .features = PHY_BASIC_FEATURES, - .flags = 0, - .probe = dp83640_probe, - .remove = dp83640_remove, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .hwtstamp = dp83640_hwtstamp, - .rxtstamp = dp83640_rxtstamp, - .txtstamp = dp83640_txtstamp, - .driver = {.owner = THIS_MODULE,} -}; - -static int __init dp83640_init(void) -{ - return phy_driver_register(&dp83640_driver); -} - -static void __exit dp83640_exit(void) -{ - dp83640_free_clocks(); - phy_driver_unregister(&dp83640_driver); -} - -MODULE_DESCRIPTION("National Semiconductor DP83640 PHY driver"); -MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.at>"); -MODULE_LICENSE("GPL"); - -module_init(dp83640_init); -module_exit(dp83640_exit); - -static struct mdio_device_id __maybe_unused dp83640_tbl[] = { - { DP83640_PHY_ID, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, dp83640_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/dp83640_reg.h b/ANDROID_3.4.5/drivers/net/phy/dp83640_reg.h deleted file mode 100644 index e7fe4111..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/dp83640_reg.h +++ /dev/null @@ -1,267 +0,0 @@ -/* dp83640_reg.h - * Generated by regen.tcl on Thu Feb 17 10:02:48 AM CET 2011 - */ -#ifndef HAVE_DP83640_REGISTERS -#define HAVE_DP83640_REGISTERS - -#define PAGE0 0x0000 -#define PHYCR2 0x001c /* PHY Control Register 2 */ - -#define PAGE4 0x0004 -#define PTP_CTL 0x0014 /* PTP Control Register */ -#define PTP_TDR 0x0015 /* PTP Time Data Register */ -#define PTP_STS 0x0016 /* PTP Status Register */ -#define PTP_TSTS 0x0017 /* PTP Trigger Status Register */ -#define PTP_RATEL 0x0018 /* PTP Rate Low Register */ -#define PTP_RATEH 0x0019 /* PTP Rate High Register */ -#define PTP_RDCKSUM 0x001a /* PTP Read Checksum */ -#define PTP_WRCKSUM 0x001b /* PTP Write Checksum */ -#define PTP_TXTS 0x001c /* PTP Transmit Timestamp Register, in four 16-bit reads */ -#define PTP_RXTS 0x001d /* PTP Receive Timestamp Register, in six? 16-bit reads */ -#define PTP_ESTS 0x001e /* PTP Event Status Register */ -#define PTP_EDATA 0x001f /* PTP Event Data Register */ - -#define PAGE5 0x0005 -#define PTP_TRIG 0x0014 /* PTP Trigger Configuration Register */ -#define PTP_EVNT 0x0015 /* PTP Event Configuration Register */ -#define PTP_TXCFG0 0x0016 /* PTP Transmit Configuration Register 0 */ -#define PTP_TXCFG1 0x0017 /* PTP Transmit Configuration Register 1 */ -#define PSF_CFG0 0x0018 /* PHY Status Frame Configuration Register 0 */ -#define PTP_RXCFG0 0x0019 /* PTP Receive Configuration Register 0 */ -#define PTP_RXCFG1 0x001a /* PTP Receive Configuration Register 1 */ -#define PTP_RXCFG2 0x001b /* PTP Receive Configuration Register 2 */ -#define PTP_RXCFG3 0x001c /* PTP Receive Configuration Register 3 */ -#define PTP_RXCFG4 0x001d /* PTP Receive Configuration Register 4 */ -#define PTP_TRDL 0x001e /* PTP Temporary Rate Duration Low Register */ -#define PTP_TRDH 0x001f /* PTP Temporary Rate Duration High Register */ - -#define PAGE6 0x0006 -#define PTP_COC 0x0014 /* PTP Clock Output Control Register */ -#define PSF_CFG1 0x0015 /* PHY Status Frame Configuration Register 1 */ -#define PSF_CFG2 0x0016 /* PHY Status Frame Configuration Register 2 */ -#define PSF_CFG3 0x0017 /* PHY Status Frame Configuration Register 3 */ -#define PSF_CFG4 0x0018 /* PHY Status Frame Configuration Register 4 */ -#define PTP_SFDCFG 0x0019 /* PTP SFD Configuration Register */ -#define PTP_INTCTL 0x001a /* PTP Interrupt Control Register */ -#define PTP_CLKSRC 0x001b /* PTP Clock Source Register */ -#define PTP_ETR 0x001c /* PTP Ethernet Type Register */ -#define PTP_OFF 0x001d /* PTP Offset Register */ -#define PTP_GPIOMON 0x001e /* PTP GPIO Monitor Register */ -#define PTP_RXHASH 0x001f /* PTP Receive Hash Register */ - -/* Bit definitions for the PHYCR2 register */ -#define BC_WRITE (1<<11) /* Broadcast Write Enable */ - -/* Bit definitions for the PTP_CTL register */ -#define TRIG_SEL_SHIFT (10) /* PTP Trigger Select */ -#define TRIG_SEL_MASK (0x7) -#define TRIG_DIS (1<<9) /* Disable PTP Trigger */ -#define TRIG_EN (1<<8) /* Enable PTP Trigger */ -#define TRIG_READ (1<<7) /* Read PTP Trigger */ -#define TRIG_LOAD (1<<6) /* Load PTP Trigger */ -#define PTP_RD_CLK (1<<5) /* Read PTP Clock */ -#define PTP_LOAD_CLK (1<<4) /* Load PTP Clock */ -#define PTP_STEP_CLK (1<<3) /* Step PTP Clock */ -#define PTP_ENABLE (1<<2) /* Enable PTP Clock */ -#define PTP_DISABLE (1<<1) /* Disable PTP Clock */ -#define PTP_RESET (1<<0) /* Reset PTP Clock */ - -/* Bit definitions for the PTP_STS register */ -#define TXTS_RDY (1<<11) /* Transmit Timestamp Ready */ -#define RXTS_RDY (1<<10) /* Receive Timestamp Ready */ -#define TRIG_DONE (1<<9) /* PTP Trigger Done */ -#define EVENT_RDY (1<<8) /* PTP Event Timestamp Ready */ -#define TXTS_IE (1<<3) /* Transmit Timestamp Interrupt Enable */ -#define RXTS_IE (1<<2) /* Receive Timestamp Interrupt Enable */ -#define TRIG_IE (1<<1) /* Trigger Interrupt Enable */ -#define EVENT_IE (1<<0) /* Event Interrupt Enable */ - -/* Bit definitions for the PTP_TSTS register */ -#define TRIG7_ERROR (1<<15) /* Trigger 7 Error */ -#define TRIG7_ACTIVE (1<<14) /* Trigger 7 Active */ -#define TRIG6_ERROR (1<<13) /* Trigger 6 Error */ -#define TRIG6_ACTIVE (1<<12) /* Trigger 6 Active */ -#define TRIG5_ERROR (1<<11) /* Trigger 5 Error */ -#define TRIG5_ACTIVE (1<<10) /* Trigger 5 Active */ -#define TRIG4_ERROR (1<<9) /* Trigger 4 Error */ -#define TRIG4_ACTIVE (1<<8) /* Trigger 4 Active */ -#define TRIG3_ERROR (1<<7) /* Trigger 3 Error */ -#define TRIG3_ACTIVE (1<<6) /* Trigger 3 Active */ -#define TRIG2_ERROR (1<<5) /* Trigger 2 Error */ -#define TRIG2_ACTIVE (1<<4) /* Trigger 2 Active */ -#define TRIG1_ERROR (1<<3) /* Trigger 1 Error */ -#define TRIG1_ACTIVE (1<<2) /* Trigger 1 Active */ -#define TRIG0_ERROR (1<<1) /* Trigger 0 Error */ -#define TRIG0_ACTIVE (1<<0) /* Trigger 0 Active */ - -/* Bit definitions for the PTP_RATEH register */ -#define PTP_RATE_DIR (1<<15) /* PTP Rate Direction */ -#define PTP_TMP_RATE (1<<14) /* PTP Temporary Rate */ -#define PTP_RATE_HI_SHIFT (0) /* PTP Rate High 10-bits */ -#define PTP_RATE_HI_MASK (0x3ff) - -/* Bit definitions for the PTP_ESTS register */ -#define EVNTS_MISSED_SHIFT (8) /* Indicates number of events missed */ -#define EVNTS_MISSED_MASK (0x7) -#define EVNT_TS_LEN_SHIFT (6) /* Indicates length of the Timestamp field in 16-bit words minus 1 */ -#define EVNT_TS_LEN_MASK (0x3) -#define EVNT_RF (1<<5) /* Indicates whether the event is a rise or falling event */ -#define EVNT_NUM_SHIFT (2) /* Indicates Event Timestamp Unit which detected an event */ -#define EVNT_NUM_MASK (0x7) -#define MULT_EVNT (1<<1) /* Indicates multiple events were detected at the same time */ -#define EVENT_DET (1<<0) /* PTP Event Detected */ - -/* Bit definitions for the PTP_EDATA register */ -#define E7_RISE (1<<15) /* Indicates direction of Event 7 */ -#define E7_DET (1<<14) /* Indicates Event 7 detected */ -#define E6_RISE (1<<13) /* Indicates direction of Event 6 */ -#define E6_DET (1<<12) /* Indicates Event 6 detected */ -#define E5_RISE (1<<11) /* Indicates direction of Event 5 */ -#define E5_DET (1<<10) /* Indicates Event 5 detected */ -#define E4_RISE (1<<9) /* Indicates direction of Event 4 */ -#define E4_DET (1<<8) /* Indicates Event 4 detected */ -#define E3_RISE (1<<7) /* Indicates direction of Event 3 */ -#define E3_DET (1<<6) /* Indicates Event 3 detected */ -#define E2_RISE (1<<5) /* Indicates direction of Event 2 */ -#define E2_DET (1<<4) /* Indicates Event 2 detected */ -#define E1_RISE (1<<3) /* Indicates direction of Event 1 */ -#define E1_DET (1<<2) /* Indicates Event 1 detected */ -#define E0_RISE (1<<1) /* Indicates direction of Event 0 */ -#define E0_DET (1<<0) /* Indicates Event 0 detected */ - -/* Bit definitions for the PTP_TRIG register */ -#define TRIG_PULSE (1<<15) /* generate a Pulse rather than a single edge */ -#define TRIG_PER (1<<14) /* generate a periodic signal */ -#define TRIG_IF_LATE (1<<13) /* trigger immediately if already past */ -#define TRIG_NOTIFY (1<<12) /* Trigger Notification Enable */ -#define TRIG_GPIO_SHIFT (8) /* Trigger GPIO Connection, value 1-12 */ -#define TRIG_GPIO_MASK (0xf) -#define TRIG_TOGGLE (1<<7) /* Trigger Toggle Mode Enable */ -#define TRIG_CSEL_SHIFT (1) /* Trigger Configuration Select */ -#define TRIG_CSEL_MASK (0x7) -#define TRIG_WR (1<<0) /* Trigger Configuration Write */ - -/* Bit definitions for the PTP_EVNT register */ -#define EVNT_RISE (1<<14) /* Event Rise Detect Enable */ -#define EVNT_FALL (1<<13) /* Event Fall Detect Enable */ -#define EVNT_SINGLE (1<<12) /* enable single event capture operation */ -#define EVNT_GPIO_SHIFT (8) /* Event GPIO Connection, value 1-12 */ -#define EVNT_GPIO_MASK (0xf) -#define EVNT_SEL_SHIFT (1) /* Event Select */ -#define EVNT_SEL_MASK (0x7) -#define EVNT_WR (1<<0) /* Event Configuration Write */ - -/* Bit definitions for the PTP_TXCFG0 register */ -#define SYNC_1STEP (1<<15) /* insert timestamp into transmit Sync Messages */ -#define DR_INSERT (1<<13) /* Insert Delay_Req Timestamp in Delay_Resp (dangerous) */ -#define NTP_TS_EN (1<<12) /* Enable Timestamping of NTP Packets */ -#define IGNORE_2STEP (1<<11) /* Ignore Two_Step flag for One-Step operation */ -#define CRC_1STEP (1<<10) /* Disable checking of CRC for One-Step operation */ -#define CHK_1STEP (1<<9) /* Enable UDP Checksum correction for One-Step Operation */ -#define IP1588_EN (1<<8) /* Enable IEEE 1588 defined IP address filter */ -#define TX_L2_EN (1<<7) /* Layer2 Timestamp Enable */ -#define TX_IPV6_EN (1<<6) /* IPv6 Timestamp Enable */ -#define TX_IPV4_EN (1<<5) /* IPv4 Timestamp Enable */ -#define TX_PTP_VER_SHIFT (1) /* Enable Timestamp capture for IEEE 1588 version X */ -#define TX_PTP_VER_MASK (0xf) -#define TX_TS_EN (1<<0) /* Transmit Timestamp Enable */ - -/* Bit definitions for the PTP_TXCFG1 register */ -#define BYTE0_MASK_SHIFT (8) /* Bit mask to be used for matching Byte0 of the PTP Message */ -#define BYTE0_MASK_MASK (0xff) -#define BYTE0_DATA_SHIFT (0) /* Data to be used for matching Byte0 of the PTP Message */ -#define BYTE0_DATA_MASK (0xff) - -/* Bit definitions for the PSF_CFG0 register */ -#define MAC_SRC_ADD_SHIFT (11) /* Status Frame Mac Source Address */ -#define MAC_SRC_ADD_MASK (0x3) -#define MIN_PRE_SHIFT (8) /* Status Frame Minimum Preamble */ -#define MIN_PRE_MASK (0x7) -#define PSF_ENDIAN (1<<7) /* Status Frame Endian Control */ -#define PSF_IPV4 (1<<6) /* Status Frame IPv4 Enable */ -#define PSF_PCF_RD (1<<5) /* Control Frame Read PHY Status Frame Enable */ -#define PSF_ERR_EN (1<<4) /* Error PHY Status Frame Enable */ -#define PSF_TXTS_EN (1<<3) /* Transmit Timestamp PHY Status Frame Enable */ -#define PSF_RXTS_EN (1<<2) /* Receive Timestamp PHY Status Frame Enable */ -#define PSF_TRIG_EN (1<<1) /* Trigger PHY Status Frame Enable */ -#define PSF_EVNT_EN (1<<0) /* Event PHY Status Frame Enable */ - -/* Bit definitions for the PTP_RXCFG0 register */ -#define DOMAIN_EN (1<<15) /* Domain Match Enable */ -#define ALT_MAST_DIS (1<<14) /* Alternate Master Timestamp Disable */ -#define USER_IP_SEL (1<<13) /* Selects portion of IP address accessible thru PTP_RXCFG2 */ -#define USER_IP_EN (1<<12) /* Enable User-programmed IP address filter */ -#define RX_SLAVE (1<<11) /* Receive Slave Only */ -#define IP1588_EN_SHIFT (8) /* Enable IEEE 1588 defined IP address filters */ -#define IP1588_EN_MASK (0xf) -#define RX_L2_EN (1<<7) /* Layer2 Timestamp Enable */ -#define RX_IPV6_EN (1<<6) /* IPv6 Timestamp Enable */ -#define RX_IPV4_EN (1<<5) /* IPv4 Timestamp Enable */ -#define RX_PTP_VER_SHIFT (1) /* Enable Timestamp capture for IEEE 1588 version X */ -#define RX_PTP_VER_MASK (0xf) -#define RX_TS_EN (1<<0) /* Receive Timestamp Enable */ - -/* Bit definitions for the PTP_RXCFG1 register */ -#define BYTE0_MASK_SHIFT (8) /* Bit mask to be used for matching Byte0 of the PTP Message */ -#define BYTE0_MASK_MASK (0xff) -#define BYTE0_DATA_SHIFT (0) /* Data to be used for matching Byte0 of the PTP Message */ -#define BYTE0_DATA_MASK (0xff) - -/* Bit definitions for the PTP_RXCFG3 register */ -#define TS_MIN_IFG_SHIFT (12) /* Minimum Inter-frame Gap */ -#define TS_MIN_IFG_MASK (0xf) -#define ACC_UDP (1<<11) /* Record Timestamp if UDP Checksum Error */ -#define ACC_CRC (1<<10) /* Record Timestamp if CRC Error */ -#define TS_APPEND (1<<9) /* Append Timestamp for L2 */ -#define TS_INSERT (1<<8) /* Enable Timestamp Insertion */ -#define PTP_DOMAIN_SHIFT (0) /* PTP Message domainNumber field */ -#define PTP_DOMAIN_MASK (0xff) - -/* Bit definitions for the PTP_RXCFG4 register */ -#define IPV4_UDP_MOD (1<<15) /* Enable IPV4 UDP Modification */ -#define TS_SEC_EN (1<<14) /* Enable Timestamp Seconds */ -#define TS_SEC_LEN_SHIFT (12) /* Inserted Timestamp Seconds Length */ -#define TS_SEC_LEN_MASK (0x3) -#define RXTS_NS_OFF_SHIFT (6) /* Receive Timestamp Nanoseconds offset */ -#define RXTS_NS_OFF_MASK (0x3f) -#define RXTS_SEC_OFF_SHIFT (0) /* Receive Timestamp Seconds offset */ -#define RXTS_SEC_OFF_MASK (0x3f) - -/* Bit definitions for the PTP_COC register */ -#define PTP_CLKOUT_EN (1<<15) /* PTP Clock Output Enable */ -#define PTP_CLKOUT_SEL (1<<14) /* PTP Clock Output Source Select */ -#define PTP_CLKOUT_SPEEDSEL (1<<13) /* PTP Clock Output I/O Speed Select */ -#define PTP_CLKDIV_SHIFT (0) /* PTP Clock Divide-by Value */ -#define PTP_CLKDIV_MASK (0xff) - -/* Bit definitions for the PSF_CFG1 register */ -#define PTPRESERVED_SHIFT (12) /* PTP v2 reserved field */ -#define PTPRESERVED_MASK (0xf) -#define VERSIONPTP_SHIFT (8) /* PTP v2 versionPTP field */ -#define VERSIONPTP_MASK (0xf) -#define TRANSPORT_SPECIFIC_SHIFT (4) /* PTP v2 Header transportSpecific field */ -#define TRANSPORT_SPECIFIC_MASK (0xf) -#define MESSAGETYPE_SHIFT (0) /* PTP v2 messageType field */ -#define MESSAGETYPE_MASK (0xf) - -/* Bit definitions for the PTP_SFDCFG register */ -#define TX_SFD_GPIO_SHIFT (4) /* TX SFD GPIO Select, value 1-12 */ -#define TX_SFD_GPIO_MASK (0xf) -#define RX_SFD_GPIO_SHIFT (0) /* RX SFD GPIO Select, value 1-12 */ -#define RX_SFD_GPIO_MASK (0xf) - -/* Bit definitions for the PTP_INTCTL register */ -#define PTP_INT_GPIO_SHIFT (0) /* PTP Interrupt GPIO Select */ -#define PTP_INT_GPIO_MASK (0xf) - -/* Bit definitions for the PTP_CLKSRC register */ -#define CLK_SRC_SHIFT (14) /* PTP Clock Source Select */ -#define CLK_SRC_MASK (0x3) -#define CLK_SRC_PER_SHIFT (0) /* PTP Clock Source Period */ -#define CLK_SRC_PER_MASK (0x7f) - -/* Bit definitions for the PTP_OFF register */ -#define PTP_OFFSET_SHIFT (0) /* PTP Message offset from preceding header */ -#define PTP_OFFSET_MASK (0xff) - -#endif diff --git a/ANDROID_3.4.5/drivers/net/phy/et1011c.c b/ANDROID_3.4.5/drivers/net/phy/et1011c.c deleted file mode 100644 index a8eb19ec..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/et1011c.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * drivers/net/phy/et1011c.c - * - * Driver for LSI ET1011C PHYs - * - * Author: Chaithrika U S - * - * Copyright (c) 2008 Texas Instruments - * - * 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> -#include <linux/io.h> -#include <linux/uaccess.h> -#include <asm/irq.h> - -#define ET1011C_STATUS_REG (0x1A) -#define ET1011C_CONFIG_REG (0x16) -#define ET1011C_SPEED_MASK (0x0300) -#define ET1011C_GIGABIT_SPEED (0x0200) -#define ET1011C_TX_FIFO_MASK (0x3000) -#define ET1011C_TX_FIFO_DEPTH_8 (0x0000) -#define ET1011C_TX_FIFO_DEPTH_16 (0x1000) -#define ET1011C_INTERFACE_MASK (0x0007) -#define ET1011C_GMII_INTERFACE (0x0002) -#define ET1011C_SYS_CLK_EN (0x01 << 4) - - -MODULE_DESCRIPTION("LSI ET1011C PHY driver"); -MODULE_AUTHOR("Chaithrika U S"); -MODULE_LICENSE("GPL"); - -static int et1011c_config_aneg(struct phy_device *phydev) -{ - int ctl = 0; - ctl = phy_read(phydev, MII_BMCR); - if (ctl < 0) - return ctl; - ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | - BMCR_ANENABLE); - /* First clear the PHY */ - phy_write(phydev, MII_BMCR, ctl | BMCR_RESET); - - return genphy_config_aneg(phydev); -} - -static int et1011c_read_status(struct phy_device *phydev) -{ - int ret; - u32 val; - static int speed; - ret = genphy_read_status(phydev); - - if (speed != phydev->speed) { - speed = phydev->speed; - val = phy_read(phydev, ET1011C_STATUS_REG); - if ((val & ET1011C_SPEED_MASK) == - ET1011C_GIGABIT_SPEED) { - val = phy_read(phydev, ET1011C_CONFIG_REG); - val &= ~ET1011C_TX_FIFO_MASK; - phy_write(phydev, ET1011C_CONFIG_REG, val\ - | ET1011C_GMII_INTERFACE\ - | ET1011C_SYS_CLK_EN\ - | ET1011C_TX_FIFO_DEPTH_16); - - } - } - return ret; -} - -static struct phy_driver et1011c_driver = { - .phy_id = 0x0282f014, - .name = "ET1011C", - .phy_id_mask = 0xfffffff0, - .features = (PHY_BASIC_FEATURES | SUPPORTED_1000baseT_Full), - .flags = PHY_POLL, - .config_aneg = et1011c_config_aneg, - .read_status = et1011c_read_status, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init et1011c_init(void) -{ - return phy_driver_register(&et1011c_driver); -} - -static void __exit et1011c_exit(void) -{ - phy_driver_unregister(&et1011c_driver); -} - -module_init(et1011c_init); -module_exit(et1011c_exit); - -static struct mdio_device_id __maybe_unused et1011c_tbl[] = { - { 0x0282f014, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, et1011c_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/fixed.c b/ANDROID_3.4.5/drivers/net/phy/fixed.c deleted file mode 100644 index 633680d0..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/fixed.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Fixed MDIO bus (MDIO bus emulation with fixed PHYs) - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/list.h> -#include <linux/mii.h> -#include <linux/phy.h> -#include <linux/phy_fixed.h> -#include <linux/err.h> -#include <linux/slab.h> - -#define MII_REGS_NUM 29 - -struct fixed_mdio_bus { - int irqs[PHY_MAX_ADDR]; - struct mii_bus *mii_bus; - struct list_head phys; -}; - -struct fixed_phy { - int id; - u16 regs[MII_REGS_NUM]; - struct phy_device *phydev; - struct fixed_phy_status status; - int (*link_update)(struct net_device *, struct fixed_phy_status *); - struct list_head node; -}; - -static struct platform_device *pdev; -static struct fixed_mdio_bus platform_fmb = { - .phys = LIST_HEAD_INIT(platform_fmb.phys), -}; - -static int fixed_phy_update_regs(struct fixed_phy *fp) -{ - u16 bmsr = BMSR_ANEGCAPABLE; - u16 bmcr = 0; - u16 lpagb = 0; - u16 lpa = 0; - - if (fp->status.duplex) { - bmcr |= BMCR_FULLDPLX; - - switch (fp->status.speed) { - case 1000: - bmsr |= BMSR_ESTATEN; - bmcr |= BMCR_SPEED1000; - lpagb |= LPA_1000FULL; - break; - case 100: - bmsr |= BMSR_100FULL; - bmcr |= BMCR_SPEED100; - lpa |= LPA_100FULL; - break; - case 10: - bmsr |= BMSR_10FULL; - lpa |= LPA_10FULL; - break; - default: - printk(KERN_WARNING "fixed phy: unknown speed\n"); - return -EINVAL; - } - } else { - switch (fp->status.speed) { - case 1000: - bmsr |= BMSR_ESTATEN; - bmcr |= BMCR_SPEED1000; - lpagb |= LPA_1000HALF; - break; - case 100: - bmsr |= BMSR_100HALF; - bmcr |= BMCR_SPEED100; - lpa |= LPA_100HALF; - break; - case 10: - bmsr |= BMSR_10HALF; - lpa |= LPA_10HALF; - break; - default: - printk(KERN_WARNING "fixed phy: unknown speed\n"); - return -EINVAL; - } - } - - if (fp->status.link) - bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE; - - if (fp->status.pause) - lpa |= LPA_PAUSE_CAP; - - if (fp->status.asym_pause) - lpa |= LPA_PAUSE_ASYM; - - fp->regs[MII_PHYSID1] = fp->id >> 16; - fp->regs[MII_PHYSID2] = fp->id; - - fp->regs[MII_BMSR] = bmsr; - fp->regs[MII_BMCR] = bmcr; - fp->regs[MII_LPA] = lpa; - fp->regs[MII_STAT1000] = lpagb; - - return 0; -} - -static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num) -{ - struct fixed_mdio_bus *fmb = bus->priv; - struct fixed_phy *fp; - - if (reg_num >= MII_REGS_NUM) - return -1; - - list_for_each_entry(fp, &fmb->phys, node) { - if (fp->id == phy_id) { - /* Issue callback if user registered it. */ - if (fp->link_update) { - fp->link_update(fp->phydev->attached_dev, - &fp->status); - fixed_phy_update_regs(fp); - } - return fp->regs[reg_num]; - } - } - - return 0xFFFF; -} - -static int fixed_mdio_write(struct mii_bus *bus, int phy_id, int reg_num, - u16 val) -{ - return 0; -} - -/* - * If something weird is required to be done with link/speed, - * network driver is able to assign a function to implement this. - * May be useful for PHY's that need to be software-driven. - */ -int fixed_phy_set_link_update(struct phy_device *phydev, - int (*link_update)(struct net_device *, - struct fixed_phy_status *)) -{ - struct fixed_mdio_bus *fmb = &platform_fmb; - struct fixed_phy *fp; - - if (!link_update || !phydev || !phydev->bus) - return -EINVAL; - - list_for_each_entry(fp, &fmb->phys, node) { - if (fp->id == phydev->phy_id) { - fp->link_update = link_update; - fp->phydev = phydev; - return 0; - } - } - - return -ENOENT; -} -EXPORT_SYMBOL_GPL(fixed_phy_set_link_update); - -int fixed_phy_add(unsigned int irq, int phy_id, - struct fixed_phy_status *status) -{ - int ret; - struct fixed_mdio_bus *fmb = &platform_fmb; - struct fixed_phy *fp; - - fp = kzalloc(sizeof(*fp), GFP_KERNEL); - if (!fp) - return -ENOMEM; - - memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM); - - fmb->irqs[phy_id] = irq; - - fp->id = phy_id; - fp->status = *status; - - ret = fixed_phy_update_regs(fp); - if (ret) - goto err_regs; - - list_add_tail(&fp->node, &fmb->phys); - - return 0; - -err_regs: - kfree(fp); - return ret; -} -EXPORT_SYMBOL_GPL(fixed_phy_add); - -static int __init fixed_mdio_bus_init(void) -{ - struct fixed_mdio_bus *fmb = &platform_fmb; - int ret; - - pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0); - if (IS_ERR(pdev)) { - ret = PTR_ERR(pdev); - goto err_pdev; - } - - fmb->mii_bus = mdiobus_alloc(); - if (fmb->mii_bus == NULL) { - ret = -ENOMEM; - goto err_mdiobus_reg; - } - - snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0"); - fmb->mii_bus->name = "Fixed MDIO Bus"; - fmb->mii_bus->priv = fmb; - fmb->mii_bus->parent = &pdev->dev; - fmb->mii_bus->read = &fixed_mdio_read; - fmb->mii_bus->write = &fixed_mdio_write; - fmb->mii_bus->irq = fmb->irqs; - - ret = mdiobus_register(fmb->mii_bus); - if (ret) - goto err_mdiobus_alloc; - - return 0; - -err_mdiobus_alloc: - mdiobus_free(fmb->mii_bus); -err_mdiobus_reg: - platform_device_unregister(pdev); -err_pdev: - return ret; -} -module_init(fixed_mdio_bus_init); - -static void __exit fixed_mdio_bus_exit(void) -{ - struct fixed_mdio_bus *fmb = &platform_fmb; - struct fixed_phy *fp, *tmp; - - mdiobus_unregister(fmb->mii_bus); - mdiobus_free(fmb->mii_bus); - platform_device_unregister(pdev); - - list_for_each_entry_safe(fp, tmp, &fmb->phys, node) { - list_del(&fp->node); - kfree(fp); - } -} -module_exit(fixed_mdio_bus_exit); - -MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)"); -MODULE_AUTHOR("Vitaly Bordug"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/net/phy/icplus.c b/ANDROID_3.4.5/drivers/net/phy/icplus.c deleted file mode 100644 index 5ac46f52..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/icplus.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Driver for ICPlus PHYs - * - * Copyright (c) 2007 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers"); -MODULE_AUTHOR("Michael Barkowski"); -MODULE_LICENSE("GPL"); - -/* IP101A/G - IP1001 */ -#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ -#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ -#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ -#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ -#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ -#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ - -static int ip175c_config_init(struct phy_device *phydev) -{ - int err, i; - static int full_reset_performed = 0; - - if (full_reset_performed == 0) { - - /* master reset */ - err = mdiobus_write(phydev->bus, 30, 0, 0x175c); - if (err < 0) - return err; - - /* ensure no bus delays overlap reset period */ - err = mdiobus_read(phydev->bus, 30, 0); - - /* data sheet specifies reset period is 2 msec */ - mdelay(2); - - /* enable IP175C mode */ - err = mdiobus_write(phydev->bus, 29, 31, 0x175c); - if (err < 0) - return err; - - /* Set MII0 speed and duplex (in PHY mode) */ - err = mdiobus_write(phydev->bus, 29, 22, 0x420); - if (err < 0) - return err; - - /* reset switch ports */ - for (i = 0; i < 5; i++) { - err = mdiobus_write(phydev->bus, i, - MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - } - - for (i = 0; i < 5; i++) - err = mdiobus_read(phydev->bus, i, MII_BMCR); - - mdelay(2); - - full_reset_performed = 1; - } - - if (phydev->addr != 4) { - phydev->state = PHY_RUNNING; - phydev->speed = SPEED_100; - phydev->duplex = DUPLEX_FULL; - phydev->link = 1; - netif_carrier_on(phydev->attached_dev); - } - - return 0; -} - -static int ip1xx_reset(struct phy_device *phydev) -{ - int bmcr; - - /* Software Reset PHY */ - bmcr = phy_read(phydev, MII_BMCR); - if (bmcr < 0) - return bmcr; - bmcr |= BMCR_RESET; - bmcr = phy_write(phydev, MII_BMCR, bmcr); - if (bmcr < 0) - return bmcr; - - do { - bmcr = phy_read(phydev, MII_BMCR); - if (bmcr < 0) - return bmcr; - } while (bmcr & BMCR_RESET); - - return 0; -} - -static int ip1001_config_init(struct phy_device *phydev) -{ - int c; - - c = ip1xx_reset(phydev); - if (c < 0) - return c; - - /* Enable Auto Power Saving mode */ - c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2); - if (c < 0) - return c; - c |= IP1001_APS_ON; - c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c); - if (c < 0) - return c; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { - /* Additional delay (2ns) used to adjust RX clock phase - * at RGMII interface */ - c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); - if (c < 0) - return c; - - c |= IP1001_PHASE_SEL_MASK; - c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); - if (c < 0) - return c; - } - - return 0; -} - -static int ip101a_g_config_init(struct phy_device *phydev) -{ - int c; - - c = ip1xx_reset(phydev); - if (c < 0) - return c; - - /* Enable Auto Power Saving mode */ - c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); - c |= IP101A_G_APS_ON; - - return phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); -} - -static int ip175c_read_status(struct phy_device *phydev) -{ - if (phydev->addr == 4) /* WAN port */ - genphy_read_status(phydev); - else - /* Don't need to read status for switch ports */ - phydev->irq = PHY_IGNORE_INTERRUPT; - - return 0; -} - -static int ip175c_config_aneg(struct phy_device *phydev) -{ - if (phydev->addr == 4) /* WAN port */ - genphy_config_aneg(phydev); - - return 0; -} - -static int ip101a_g_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); - if (err < 0) - return err; - - return 0; -} - -static struct phy_driver ip175c_driver = { - .phy_id = 0x02430d80, - .name = "ICPlus IP175C", - .phy_id_mask = 0x0ffffff0, - .features = PHY_BASIC_FEATURES, - .config_init = &ip175c_config_init, - .config_aneg = &ip175c_config_aneg, - .read_status = &ip175c_read_status, - .suspend = genphy_suspend, - .resume = genphy_resume, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver ip1001_driver = { - .phy_id = 0x02430d90, - .name = "ICPlus IP1001", - .phy_id_mask = 0x0ffffff0, - .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | - SUPPORTED_Asym_Pause, - .config_init = &ip1001_config_init, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .suspend = genphy_suspend, - .resume = genphy_resume, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver ip101a_g_driver = { - .phy_id = 0x02430c54, - .name = "ICPlus IP101A/G", - .phy_id_mask = 0x0ffffff0, - .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | - SUPPORTED_Asym_Pause, - .flags = PHY_HAS_INTERRUPT, - .ack_interrupt = ip101a_g_ack_interrupt, - .config_init = &ip101a_g_config_init, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .suspend = genphy_suspend, - .resume = genphy_resume, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init icplus_init(void) -{ - int ret = 0; - - ret = phy_driver_register(&ip1001_driver); - if (ret < 0) - return -ENODEV; - - ret = phy_driver_register(&ip101a_g_driver); - if (ret < 0) - return -ENODEV; - - return phy_driver_register(&ip175c_driver); -} - -static void __exit icplus_exit(void) -{ - phy_driver_unregister(&ip1001_driver); - phy_driver_unregister(&ip101a_g_driver); - phy_driver_unregister(&ip175c_driver); -} - -module_init(icplus_init); -module_exit(icplus_exit); - -static struct mdio_device_id __maybe_unused icplus_tbl[] = { - { 0x02430d80, 0x0ffffff0 }, - { 0x02430d90, 0x0ffffff0 }, - { 0x02430c54, 0x0ffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, icplus_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/lxt.c b/ANDROID_3.4.5/drivers/net/phy/lxt.c deleted file mode 100644 index 6f6e8b61..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/lxt.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * drivers/net/phy/lxt.c - * - * Driver for Intel LXT PHYs - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -/* The Level one LXT970 is used by many boards */ - -#define MII_LXT970_IER 17 /* Interrupt Enable Register */ - -#define MII_LXT970_IER_IEN 0x0002 - -#define MII_LXT970_ISR 18 /* Interrupt Status Register */ - -#define MII_LXT970_CONFIG 19 /* Configuration Register */ - -/* ------------------------------------------------------------------------- */ -/* The Level one LXT971 is used on some of my custom boards */ - -/* register definitions for the 971 */ -#define MII_LXT971_IER 18 /* Interrupt Enable Register */ -#define MII_LXT971_IER_IEN 0x00f2 - -#define MII_LXT971_ISR 19 /* Interrupt Status Register */ - -/* register definitions for the 973 */ -#define MII_LXT973_PCR 16 /* Port Configuration Register */ -#define PCR_FIBER_SELECT 1 - -MODULE_DESCRIPTION("Intel LXT PHY driver"); -MODULE_AUTHOR("Andy Fleming"); -MODULE_LICENSE("GPL"); - -static int lxt970_ack_interrupt(struct phy_device *phydev) -{ - int err; - - err = phy_read(phydev, MII_BMSR); - - if (err < 0) - return err; - - err = phy_read(phydev, MII_LXT970_ISR); - - if (err < 0) - return err; - - return 0; -} - -static int lxt970_config_intr(struct phy_device *phydev) -{ - int err; - - if(phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_LXT970_IER, MII_LXT970_IER_IEN); - else - err = phy_write(phydev, MII_LXT970_IER, 0); - - return err; -} - -static int lxt970_config_init(struct phy_device *phydev) -{ - int err; - - err = phy_write(phydev, MII_LXT970_CONFIG, 0); - - return err; -} - - -static int lxt971_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, MII_LXT971_ISR); - - if (err < 0) - return err; - - return 0; -} - -static int lxt971_config_intr(struct phy_device *phydev) -{ - int err; - - if(phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_LXT971_IER, MII_LXT971_IER_IEN); - else - err = phy_write(phydev, MII_LXT971_IER, 0); - - return err; -} - -static int lxt973_probe(struct phy_device *phydev) -{ - int val = phy_read(phydev, MII_LXT973_PCR); - - if (val & PCR_FIBER_SELECT) { - /* - * If fiber is selected, then the only correct setting - * is 100Mbps, full duplex, and auto negotiation off. - */ - val = phy_read(phydev, MII_BMCR); - val |= (BMCR_SPEED100 | BMCR_FULLDPLX); - val &= ~BMCR_ANENABLE; - phy_write(phydev, MII_BMCR, val); - /* Remember that the port is in fiber mode. */ - phydev->priv = lxt973_probe; - } else { - phydev->priv = NULL; - } - return 0; -} - -static int lxt973_config_aneg(struct phy_device *phydev) -{ - /* Do nothing if port is in fiber mode. */ - return phydev->priv ? 0 : genphy_config_aneg(phydev); -} - -static struct phy_driver lxt970_driver = { - .phy_id = 0x78100000, - .name = "LXT970", - .phy_id_mask = 0xfffffff0, - .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = lxt970_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = lxt970_ack_interrupt, - .config_intr = lxt970_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver lxt971_driver = { - .phy_id = 0x001378e0, - .name = "LXT971", - .phy_id_mask = 0xfffffff0, - .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = lxt971_ack_interrupt, - .config_intr = lxt971_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver lxt973_driver = { - .phy_id = 0x00137a10, - .name = "LXT973", - .phy_id_mask = 0xfffffff0, - .features = PHY_BASIC_FEATURES, - .flags = 0, - .probe = lxt973_probe, - .config_aneg = lxt973_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init lxt_init(void) -{ - int ret; - - ret = phy_driver_register(&lxt970_driver); - if (ret) - goto err1; - - ret = phy_driver_register(&lxt971_driver); - if (ret) - goto err2; - - ret = phy_driver_register(&lxt973_driver); - if (ret) - goto err3; - return 0; - - err3: - phy_driver_unregister(&lxt971_driver); - err2: - phy_driver_unregister(&lxt970_driver); - err1: - return ret; -} - -static void __exit lxt_exit(void) -{ - phy_driver_unregister(&lxt970_driver); - phy_driver_unregister(&lxt971_driver); - phy_driver_unregister(&lxt973_driver); -} - -module_init(lxt_init); -module_exit(lxt_exit); - -static struct mdio_device_id __maybe_unused lxt_tbl[] = { - { 0x78100000, 0xfffffff0 }, - { 0x001378e0, 0xfffffff0 }, - { 0x00137a10, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, lxt_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/marvell.c b/ANDROID_3.4.5/drivers/net/phy/marvell.c deleted file mode 100644 index e8b9c53c..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/marvell.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * drivers/net/phy/marvell.c - * - * Driver for Marvell PHYs - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> -#include <linux/marvell_phy.h> -#include <linux/of.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -#define MII_MARVELL_PHY_PAGE 22 - -#define MII_M1011_IEVENT 0x13 -#define MII_M1011_IEVENT_CLEAR 0x0000 - -#define MII_M1011_IMASK 0x12 -#define MII_M1011_IMASK_INIT 0x6400 -#define MII_M1011_IMASK_CLEAR 0x0000 - -#define MII_M1011_PHY_SCR 0x10 -#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 - -#define MII_M1145_PHY_EXT_CR 0x14 -#define MII_M1145_RGMII_RX_DELAY 0x0080 -#define MII_M1145_RGMII_TX_DELAY 0x0002 - -#define MII_M1111_PHY_LED_CONTROL 0x18 -#define MII_M1111_PHY_LED_DIRECT 0x4100 -#define MII_M1111_PHY_LED_COMBINE 0x411c -#define MII_M1111_PHY_EXT_CR 0x14 -#define MII_M1111_RX_DELAY 0x80 -#define MII_M1111_TX_DELAY 0x2 -#define MII_M1111_PHY_EXT_SR 0x1b - -#define MII_M1111_HWCFG_MODE_MASK 0xf -#define MII_M1111_HWCFG_MODE_COPPER_RGMII 0xb -#define MII_M1111_HWCFG_MODE_FIBER_RGMII 0x3 -#define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4 -#define MII_M1111_HWCFG_MODE_COPPER_RTBI 0x9 -#define MII_M1111_HWCFG_FIBER_COPPER_AUTO 0x8000 -#define MII_M1111_HWCFG_FIBER_COPPER_RES 0x2000 - -#define MII_M1111_COPPER 0 -#define MII_M1111_FIBER 1 - -#define MII_88E1121_PHY_MSCR_PAGE 2 -#define MII_88E1121_PHY_MSCR_REG 21 -#define MII_88E1121_PHY_MSCR_RX_DELAY BIT(5) -#define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4) -#define MII_88E1121_PHY_MSCR_DELAY_MASK (~(0x3 << 4)) - -#define MII_88E1318S_PHY_MSCR1_REG 16 -#define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6) - -#define MII_88E1121_PHY_LED_CTRL 16 -#define MII_88E1121_PHY_LED_PAGE 3 -#define MII_88E1121_PHY_LED_DEF 0x0030 - -#define MII_M1011_PHY_STATUS 0x11 -#define MII_M1011_PHY_STATUS_1000 0x8000 -#define MII_M1011_PHY_STATUS_100 0x4000 -#define MII_M1011_PHY_STATUS_SPD_MASK 0xc000 -#define MII_M1011_PHY_STATUS_FULLDUPLEX 0x2000 -#define MII_M1011_PHY_STATUS_RESOLVED 0x0800 -#define MII_M1011_PHY_STATUS_LINK 0x0400 - - -MODULE_DESCRIPTION("Marvell PHY driver"); -MODULE_AUTHOR("Andy Fleming"); -MODULE_LICENSE("GPL"); - -static int marvell_ack_interrupt(struct phy_device *phydev) -{ - int err; - - /* Clear the interrupts by reading the reg */ - err = phy_read(phydev, MII_M1011_IEVENT); - - if (err < 0) - return err; - - return 0; -} - -static int marvell_config_intr(struct phy_device *phydev) -{ - int err; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); - else - err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); - - return err; -} - -static int marvell_config_aneg(struct phy_device *phydev) -{ - int err; - - /* The Marvell PHY has an errata which requires - * that certain registers get written in order - * to restart autonegotiation */ - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - - if (err < 0) - return err; - - err = phy_write(phydev, 0x1d, 0x1f); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1e, 0x200c); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1d, 0x5); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1e, 0); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1e, 0x100); - if (err < 0) - return err; - - err = phy_write(phydev, MII_M1011_PHY_SCR, - MII_M1011_PHY_SCR_AUTO_CROSS); - if (err < 0) - return err; - - err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, - MII_M1111_PHY_LED_DIRECT); - if (err < 0) - return err; - - err = genphy_config_aneg(phydev); - if (err < 0) - return err; - - if (phydev->autoneg != AUTONEG_ENABLE) { - int bmcr; - - /* - * A write to speed/duplex bits (that is performed by - * genphy_config_aneg() call above) must be followed by - * a software reset. Otherwise, the write has no effect. - */ - bmcr = phy_read(phydev, MII_BMCR); - if (bmcr < 0) - return bmcr; - - err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET); - if (err < 0) - return err; - } - - return 0; -} - -#ifdef CONFIG_OF_MDIO -/* - * Set and/or override some configuration registers based on the - * marvell,reg-init property stored in the of_node for the phydev. - * - * marvell,reg-init = <reg-page reg mask value>,...; - * - * There may be one or more sets of <reg-page reg mask value>: - * - * reg-page: which register bank to use. - * reg: the register. - * mask: if non-zero, ANDed with existing register value. - * value: ORed with the masked value and written to the regiser. - * - */ -static int marvell_of_reg_init(struct phy_device *phydev) -{ - const __be32 *paddr; - int len, i, saved_page, current_page, page_changed, ret; - - if (!phydev->dev.of_node) - return 0; - - paddr = of_get_property(phydev->dev.of_node, "marvell,reg-init", &len); - if (!paddr || len < (4 * sizeof(*paddr))) - return 0; - - saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE); - if (saved_page < 0) - return saved_page; - page_changed = 0; - current_page = saved_page; - - ret = 0; - len /= sizeof(*paddr); - for (i = 0; i < len - 3; i += 4) { - u16 reg_page = be32_to_cpup(paddr + i); - u16 reg = be32_to_cpup(paddr + i + 1); - u16 mask = be32_to_cpup(paddr + i + 2); - u16 val_bits = be32_to_cpup(paddr + i + 3); - int val; - - if (reg_page != current_page) { - current_page = reg_page; - page_changed = 1; - ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page); - if (ret < 0) - goto err; - } - - val = 0; - if (mask) { - val = phy_read(phydev, reg); - if (val < 0) { - ret = val; - goto err; - } - val &= mask; - } - val |= val_bits; - - ret = phy_write(phydev, reg, val); - if (ret < 0) - goto err; - - } -err: - if (page_changed) { - i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page); - if (ret == 0) - ret = i; - } - return ret; -} -#else -static int marvell_of_reg_init(struct phy_device *phydev) -{ - return 0; -} -#endif /* CONFIG_OF_MDIO */ - -static int m88e1121_config_aneg(struct phy_device *phydev) -{ - int err, oldpage, mscr; - - oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); - - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, - MII_88E1121_PHY_MSCR_PAGE); - if (err < 0) - return err; - - if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { - - mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & - MII_88E1121_PHY_MSCR_DELAY_MASK; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) - mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | - MII_88E1121_PHY_MSCR_TX_DELAY); - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) - mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) - mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; - - err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); - if (err < 0) - return err; - } - - phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); - - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - - err = phy_write(phydev, MII_M1011_PHY_SCR, - MII_M1011_PHY_SCR_AUTO_CROSS); - if (err < 0) - return err; - - oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); - - phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); - phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); - phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); - - err = genphy_config_aneg(phydev); - - return err; -} - -static int m88e1318_config_aneg(struct phy_device *phydev) -{ - int err, oldpage, mscr; - - oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); - - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, - MII_88E1121_PHY_MSCR_PAGE); - if (err < 0) - return err; - - mscr = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG); - mscr |= MII_88E1318S_PHY_MSCR1_PAD_ODD; - - err = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, mscr); - if (err < 0) - return err; - - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); - if (err < 0) - return err; - - return m88e1121_config_aneg(phydev); -} - -static int m88e1111_config_init(struct phy_device *phydev) -{ - int err; - int temp; - - /* Enable Fiber/Copper auto selection */ - temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); - temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO; - phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); - - temp = phy_read(phydev, MII_BMCR); - temp |= BMCR_RESET; - phy_write(phydev, MII_BMCR, temp); - - if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { - - temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); - if (temp < 0) - return temp; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { - temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); - } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { - temp &= ~MII_M1111_TX_DELAY; - temp |= MII_M1111_RX_DELAY; - } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { - temp &= ~MII_M1111_RX_DELAY; - temp |= MII_M1111_TX_DELAY; - } - - err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); - if (err < 0) - return err; - - temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); - if (temp < 0) - return temp; - - temp &= ~(MII_M1111_HWCFG_MODE_MASK); - - if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES) - temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII; - else - temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII; - - err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); - if (err < 0) - return err; - } - - if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { - temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); - if (temp < 0) - return temp; - - temp &= ~(MII_M1111_HWCFG_MODE_MASK); - temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK; - temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; - - err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); - if (err < 0) - return err; - } - - if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { - temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); - if (temp < 0) - return temp; - temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); - err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); - if (err < 0) - return err; - - temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); - if (temp < 0) - return temp; - temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); - temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO; - err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); - if (err < 0) - return err; - - /* soft reset */ - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - do - temp = phy_read(phydev, MII_BMCR); - while (temp & BMCR_RESET); - - temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); - if (temp < 0) - return temp; - temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES); - temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO; - err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); - if (err < 0) - return err; - } - - err = marvell_of_reg_init(phydev); - if (err < 0) - return err; - - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - - return 0; -} - -static int m88e1118_config_aneg(struct phy_device *phydev) -{ - int err; - - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - - err = phy_write(phydev, MII_M1011_PHY_SCR, - MII_M1011_PHY_SCR_AUTO_CROSS); - if (err < 0) - return err; - - err = genphy_config_aneg(phydev); - return 0; -} - -static int m88e1118_config_init(struct phy_device *phydev) -{ - int err; - - /* Change address */ - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); - if (err < 0) - return err; - - /* Enable 1000 Mbit */ - err = phy_write(phydev, 0x15, 0x1070); - if (err < 0) - return err; - - /* Change address */ - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003); - if (err < 0) - return err; - - /* Adjust LED Control */ - if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS) - err = phy_write(phydev, 0x10, 0x1100); - else - err = phy_write(phydev, 0x10, 0x021e); - if (err < 0) - return err; - - err = marvell_of_reg_init(phydev); - if (err < 0) - return err; - - /* Reset address */ - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); - if (err < 0) - return err; - - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - - return 0; -} - -static int m88e1149_config_init(struct phy_device *phydev) -{ - int err; - - /* Change address */ - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); - if (err < 0) - return err; - - /* Enable 1000 Mbit */ - err = phy_write(phydev, 0x15, 0x1048); - if (err < 0) - return err; - - err = marvell_of_reg_init(phydev); - if (err < 0) - return err; - - /* Reset address */ - err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); - if (err < 0) - return err; - - err = phy_write(phydev, MII_BMCR, BMCR_RESET); - if (err < 0) - return err; - - return 0; -} - -static int m88e1145_config_init(struct phy_device *phydev) -{ - int err; - - /* Take care of errata E0 & E1 */ - err = phy_write(phydev, 0x1d, 0x001b); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1e, 0x418f); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1d, 0x0016); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1e, 0xa2da); - if (err < 0) - return err; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { - int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR); - if (temp < 0) - return temp; - - temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY); - - err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp); - if (err < 0) - return err; - - if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) { - err = phy_write(phydev, 0x1d, 0x0012); - if (err < 0) - return err; - - temp = phy_read(phydev, 0x1e); - if (temp < 0) - return temp; - - temp &= 0xf03f; - temp |= 2 << 9; /* 36 ohm */ - temp |= 2 << 6; /* 39 ohm */ - - err = phy_write(phydev, 0x1e, temp); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1d, 0x3); - if (err < 0) - return err; - - err = phy_write(phydev, 0x1e, 0x8000); - if (err < 0) - return err; - } - } - - err = marvell_of_reg_init(phydev); - if (err < 0) - return err; - - return 0; -} - -/* marvell_read_status - * - * Generic status code does not detect Fiber correctly! - * Description: - * Check the link, then figure out the current state - * by comparing what we advertise with what the link partner - * advertises. Start by checking the gigabit possibilities, - * then move on to 10/100. - */ -static int marvell_read_status(struct phy_device *phydev) -{ - int adv; - int err; - int lpa; - int status = 0; - - /* Update the link, but return if there - * was an error */ - err = genphy_update_link(phydev); - if (err) - return err; - - if (AUTONEG_ENABLE == phydev->autoneg) { - status = phy_read(phydev, MII_M1011_PHY_STATUS); - if (status < 0) - return status; - - lpa = phy_read(phydev, MII_LPA); - if (lpa < 0) - return lpa; - - adv = phy_read(phydev, MII_ADVERTISE); - if (adv < 0) - return adv; - - lpa &= adv; - - if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - status = status & MII_M1011_PHY_STATUS_SPD_MASK; - phydev->pause = phydev->asym_pause = 0; - - switch (status) { - case MII_M1011_PHY_STATUS_1000: - phydev->speed = SPEED_1000; - break; - - case MII_M1011_PHY_STATUS_100: - phydev->speed = SPEED_100; - break; - - default: - phydev->speed = SPEED_10; - break; - } - - if (phydev->duplex == DUPLEX_FULL) { - phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; - phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; - } - } else { - int bmcr = phy_read(phydev, MII_BMCR); - - if (bmcr < 0) - return bmcr; - - if (bmcr & BMCR_FULLDPLX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - if (bmcr & BMCR_SPEED1000) - phydev->speed = SPEED_1000; - else if (bmcr & BMCR_SPEED100) - phydev->speed = SPEED_100; - else - phydev->speed = SPEED_10; - - phydev->pause = phydev->asym_pause = 0; - } - - return 0; -} - -static int m88e1121_did_interrupt(struct phy_device *phydev) -{ - int imask; - - imask = phy_read(phydev, MII_M1011_IEVENT); - - if (imask & MII_M1011_IMASK_INIT) - return 1; - - return 0; -} - -static struct phy_driver marvell_drivers[] = { - { - .phy_id = MARVELL_PHY_ID_88E1101, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1101", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = { .owner = THIS_MODULE }, - }, - { - .phy_id = MARVELL_PHY_ID_88E1112, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1112", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &m88e1111_config_init, - .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = { .owner = THIS_MODULE }, - }, - { - .phy_id = MARVELL_PHY_ID_88E1111, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1111", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &m88e1111_config_init, - .config_aneg = &marvell_config_aneg, - .read_status = &marvell_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = { .owner = THIS_MODULE }, - }, - { - .phy_id = MARVELL_PHY_ID_88E1118, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1118", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &m88e1118_config_init, - .config_aneg = &m88e1118_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = {.owner = THIS_MODULE,}, - }, - { - .phy_id = MARVELL_PHY_ID_88E1121R, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1121R", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &m88e1121_config_aneg, - .read_status = &marvell_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .did_interrupt = &m88e1121_did_interrupt, - .driver = { .owner = THIS_MODULE }, - }, - { - .phy_id = MARVELL_PHY_ID_88E1318S, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1318S", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &m88e1318_config_aneg, - .read_status = &marvell_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .did_interrupt = &m88e1121_did_interrupt, - .driver = { .owner = THIS_MODULE }, - }, - { - .phy_id = MARVELL_PHY_ID_88E1145, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1145", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &m88e1145_config_init, - .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = { .owner = THIS_MODULE }, - }, - { - .phy_id = MARVELL_PHY_ID_88E1149R, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1149R", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &m88e1149_config_init, - .config_aneg = &m88e1118_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = { .owner = THIS_MODULE }, - }, - { - .phy_id = MARVELL_PHY_ID_88E1240, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E1240", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &m88e1111_config_init, - .config_aneg = &marvell_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, - .driver = { .owner = THIS_MODULE }, - }, -}; - -static int __init marvell_init(void) -{ - int ret; - int i; - - for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) { - ret = phy_driver_register(&marvell_drivers[i]); - - if (ret) { - while (i-- > 0) - phy_driver_unregister(&marvell_drivers[i]); - return ret; - } - } - - return 0; -} - -static void __exit marvell_exit(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) - phy_driver_unregister(&marvell_drivers[i]); -} - -module_init(marvell_init); -module_exit(marvell_exit); - -static struct mdio_device_id __maybe_unused marvell_tbl[] = { - { 0x01410c60, 0xfffffff0 }, - { 0x01410c90, 0xfffffff0 }, - { 0x01410cc0, 0xfffffff0 }, - { 0x01410e10, 0xfffffff0 }, - { 0x01410cb0, 0xfffffff0 }, - { 0x01410cd0, 0xfffffff0 }, - { 0x01410e50, 0xfffffff0 }, - { 0x01410e30, 0xfffffff0 }, - { 0x01410e90, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, marvell_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/mdio-bitbang.c b/ANDROID_3.4.5/drivers/net/phy/mdio-bitbang.c deleted file mode 100644 index daec9b05..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/mdio-bitbang.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Bitbanged MDIO support. - * - * Author: Scott Wood <scottwood@freescale.com> - * Copyright (c) 2007 Freescale Semiconductor - * - * Based on CPM2 MDIO code which is: - * - * Copyright (c) 2003 Intracom S.A. - * by Pantelis Antoniou <panto@intracom.gr> - * - * 2005 (c) MontaVista Software, Inc. - * Vitaly Bordug <vbordug@ru.mvista.com> - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include <linux/module.h> -#include <linux/mdio-bitbang.h> -#include <linux/types.h> -#include <linux/delay.h> - -#define MDIO_READ 2 -#define MDIO_WRITE 1 - -#define MDIO_C45 (1<<15) -#define MDIO_C45_ADDR (MDIO_C45 | 0) -#define MDIO_C45_READ (MDIO_C45 | 3) -#define MDIO_C45_WRITE (MDIO_C45 | 1) - -#define MDIO_SETUP_TIME 10 -#define MDIO_HOLD_TIME 10 - -/* Minimum MDC period is 400 ns, plus some margin for error. MDIO_DELAY - * is done twice per period. - */ -#define MDIO_DELAY 250 - -/* The PHY may take up to 300 ns to produce data, plus some margin - * for error. - */ -#define MDIO_READ_DELAY 350 - -/* MDIO must already be configured as output. */ -static void mdiobb_send_bit(struct mdiobb_ctrl *ctrl, int val) -{ - const struct mdiobb_ops *ops = ctrl->ops; - - ops->set_mdio_data(ctrl, val); - ndelay(MDIO_DELAY); - ops->set_mdc(ctrl, 1); - ndelay(MDIO_DELAY); - ops->set_mdc(ctrl, 0); -} - -/* MDIO must already be configured as input. */ -static int mdiobb_get_bit(struct mdiobb_ctrl *ctrl) -{ - const struct mdiobb_ops *ops = ctrl->ops; - - ndelay(MDIO_DELAY); - ops->set_mdc(ctrl, 1); - ndelay(MDIO_READ_DELAY); - ops->set_mdc(ctrl, 0); - - return ops->get_mdio_data(ctrl); -} - -/* MDIO must already be configured as output. */ -static void mdiobb_send_num(struct mdiobb_ctrl *ctrl, u16 val, int bits) -{ - int i; - - for (i = bits - 1; i >= 0; i--) - mdiobb_send_bit(ctrl, (val >> i) & 1); -} - -/* MDIO must already be configured as input. */ -static u16 mdiobb_get_num(struct mdiobb_ctrl *ctrl, int bits) -{ - int i; - u16 ret = 0; - - for (i = bits - 1; i >= 0; i--) { - ret <<= 1; - ret |= mdiobb_get_bit(ctrl); - } - - return ret; -} - -/* Utility to send the preamble, address, and - * register (common to read and write). - */ -static void mdiobb_cmd(struct mdiobb_ctrl *ctrl, int op, u8 phy, u8 reg) -{ - const struct mdiobb_ops *ops = ctrl->ops; - int i; - - ops->set_mdio_dir(ctrl, 1); - - /* - * Send a 32 bit preamble ('1's) with an extra '1' bit for good - * measure. The IEEE spec says this is a PHY optional - * requirement. The AMD 79C874 requires one after power up and - * one after a MII communications error. This means that we are - * doing more preambles than we need, but it is safer and will be - * much more robust. - */ - - for (i = 0; i < 32; i++) - mdiobb_send_bit(ctrl, 1); - - /* send the start bit (01) and the read opcode (10) or write (10). - Clause 45 operation uses 00 for the start and 11, 10 for - read/write */ - mdiobb_send_bit(ctrl, 0); - if (op & MDIO_C45) - mdiobb_send_bit(ctrl, 0); - else - mdiobb_send_bit(ctrl, 1); - mdiobb_send_bit(ctrl, (op >> 1) & 1); - mdiobb_send_bit(ctrl, (op >> 0) & 1); - - mdiobb_send_num(ctrl, phy, 5); - mdiobb_send_num(ctrl, reg, 5); -} - -/* In clause 45 mode all commands are prefixed by MDIO_ADDR to specify the - lower 16 bits of the 21 bit address. This transfer is done identically to a - MDIO_WRITE except for a different code. To enable clause 45 mode or - MII_ADDR_C45 into the address. Theoretically clause 45 and normal devices - can exist on the same bus. Normal devices should ignore the MDIO_ADDR - phase. */ -static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr) -{ - unsigned int dev_addr = (addr >> 16) & 0x1F; - unsigned int reg = addr & 0xFFFF; - mdiobb_cmd(ctrl, MDIO_C45_ADDR, phy, dev_addr); - - /* send the turnaround (10) */ - mdiobb_send_bit(ctrl, 1); - mdiobb_send_bit(ctrl, 0); - - mdiobb_send_num(ctrl, reg, 16); - - ctrl->ops->set_mdio_dir(ctrl, 0); - mdiobb_get_bit(ctrl); - - return dev_addr; -} - -static int mdiobb_read(struct mii_bus *bus, int phy, int reg) -{ - struct mdiobb_ctrl *ctrl = bus->priv; - int ret, i; - - if (reg & MII_ADDR_C45) { - reg = mdiobb_cmd_addr(ctrl, phy, reg); - mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg); - } else - mdiobb_cmd(ctrl, MDIO_READ, phy, reg); - - ctrl->ops->set_mdio_dir(ctrl, 0); - - /* check the turnaround bit: the PHY should be driving it to zero */ - if (mdiobb_get_bit(ctrl) != 0) { - /* PHY didn't drive TA low -- flush any bits it - * may be trying to send. - */ - for (i = 0; i < 32; i++) - mdiobb_get_bit(ctrl); - - return 0xffff; - } - - ret = mdiobb_get_num(ctrl, 16); - mdiobb_get_bit(ctrl); - return ret; -} - -static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) -{ - struct mdiobb_ctrl *ctrl = bus->priv; - - if (reg & MII_ADDR_C45) { - reg = mdiobb_cmd_addr(ctrl, phy, reg); - mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg); - } else - mdiobb_cmd(ctrl, MDIO_WRITE, phy, reg); - - /* send the turnaround (10) */ - mdiobb_send_bit(ctrl, 1); - mdiobb_send_bit(ctrl, 0); - - mdiobb_send_num(ctrl, val, 16); - - ctrl->ops->set_mdio_dir(ctrl, 0); - mdiobb_get_bit(ctrl); - return 0; -} - -static int mdiobb_reset(struct mii_bus *bus) -{ - struct mdiobb_ctrl *ctrl = bus->priv; - if (ctrl->reset) - ctrl->reset(bus); - return 0; -} - -struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) -{ - struct mii_bus *bus; - - bus = mdiobus_alloc(); - if (!bus) - return NULL; - - __module_get(ctrl->ops->owner); - - bus->read = mdiobb_read; - bus->write = mdiobb_write; - bus->reset = mdiobb_reset; - bus->priv = ctrl; - - return bus; -} -EXPORT_SYMBOL(alloc_mdio_bitbang); - -void free_mdio_bitbang(struct mii_bus *bus) -{ - struct mdiobb_ctrl *ctrl = bus->priv; - - module_put(ctrl->ops->owner); - mdiobus_free(bus); -} -EXPORT_SYMBOL(free_mdio_bitbang); - -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/net/phy/mdio-gpio.c b/ANDROID_3.4.5/drivers/net/phy/mdio-gpio.c deleted file mode 100644 index 7189adf5..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/mdio-gpio.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * GPIO based MDIO bitbang driver. - * Supports OpenFirmware. - * - * Copyright (c) 2008 CSE Semaphore Belgium. - * by Laurent Pinchart <laurentp@cse-semaphore.com> - * - * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * Based on earlier work by - * - * Copyright (c) 2003 Intracom S.A. - * by Pantelis Antoniou <panto@intracom.gr> - * - * 2005 (c) MontaVista Software, Inc. - * Vitaly Bordug <vbordug@ru.mvista.com> - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/mdio-gpio.h> - -#ifdef CONFIG_OF_GPIO -#include <linux/of_gpio.h> -#include <linux/of_mdio.h> -#include <linux/of_platform.h> -#endif - -struct mdio_gpio_info { - struct mdiobb_ctrl ctrl; - int mdc, mdio; -}; - -static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) -{ - struct mdio_gpio_info *bitbang = - container_of(ctrl, struct mdio_gpio_info, ctrl); - - if (dir) - gpio_direction_output(bitbang->mdio, 1); - else - gpio_direction_input(bitbang->mdio); -} - -static int mdio_get(struct mdiobb_ctrl *ctrl) -{ - struct mdio_gpio_info *bitbang = - container_of(ctrl, struct mdio_gpio_info, ctrl); - - return gpio_get_value(bitbang->mdio); -} - -static void mdio_set(struct mdiobb_ctrl *ctrl, int what) -{ - struct mdio_gpio_info *bitbang = - container_of(ctrl, struct mdio_gpio_info, ctrl); - - gpio_set_value(bitbang->mdio, what); -} - -static void mdc_set(struct mdiobb_ctrl *ctrl, int what) -{ - struct mdio_gpio_info *bitbang = - container_of(ctrl, struct mdio_gpio_info, ctrl); - - gpio_set_value(bitbang->mdc, what); -} - -static struct mdiobb_ops mdio_gpio_ops = { - .owner = THIS_MODULE, - .set_mdc = mdc_set, - .set_mdio_dir = mdio_dir, - .set_mdio_data = mdio_set, - .get_mdio_data = mdio_get, -}; - -static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev, - struct mdio_gpio_platform_data *pdata, - int bus_id) -{ - struct mii_bus *new_bus; - struct mdio_gpio_info *bitbang; - int i; - - bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); - if (!bitbang) - goto out; - - bitbang->ctrl.ops = &mdio_gpio_ops; - bitbang->ctrl.reset = pdata->reset; - bitbang->mdc = pdata->mdc; - bitbang->mdio = pdata->mdio; - - new_bus = alloc_mdio_bitbang(&bitbang->ctrl); - if (!new_bus) - goto out_free_bitbang; - - new_bus->name = "GPIO Bitbanged MDIO", - - new_bus->phy_mask = pdata->phy_mask; - new_bus->irq = pdata->irqs; - new_bus->parent = dev; - - if (new_bus->phy_mask == ~0) - goto out_free_bus; - - for (i = 0; i < PHY_MAX_ADDR; i++) - if (!new_bus->irq[i]) - new_bus->irq[i] = PHY_POLL; - - snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); - - if (gpio_request(bitbang->mdc, "mdc")) - goto out_free_bus; - - if (gpio_request(bitbang->mdio, "mdio")) - goto out_free_mdc; - - gpio_direction_output(bitbang->mdc, 0); - - dev_set_drvdata(dev, new_bus); - - return new_bus; - -out_free_mdc: - gpio_free(bitbang->mdc); -out_free_bus: - free_mdio_bitbang(new_bus); -out_free_bitbang: - kfree(bitbang); -out: - return NULL; -} - -static void mdio_gpio_bus_deinit(struct device *dev) -{ - struct mii_bus *bus = dev_get_drvdata(dev); - struct mdio_gpio_info *bitbang = bus->priv; - - dev_set_drvdata(dev, NULL); - gpio_free(bitbang->mdio); - gpio_free(bitbang->mdc); - free_mdio_bitbang(bus); - kfree(bitbang); -} - -static void __devexit mdio_gpio_bus_destroy(struct device *dev) -{ - struct mii_bus *bus = dev_get_drvdata(dev); - - mdiobus_unregister(bus); - mdio_gpio_bus_deinit(dev); -} - -static int __devinit mdio_gpio_probe(struct platform_device *pdev) -{ - struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; - struct mii_bus *new_bus; - int ret; - - if (!pdata) - return -ENODEV; - - new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); - if (!new_bus) - return -ENODEV; - - ret = mdiobus_register(new_bus); - if (ret) - mdio_gpio_bus_deinit(&pdev->dev); - - return ret; -} - -static int __devexit mdio_gpio_remove(struct platform_device *pdev) -{ - mdio_gpio_bus_destroy(&pdev->dev); - - return 0; -} - -#ifdef CONFIG_OF_GPIO - -static int __devinit mdio_ofgpio_probe(struct platform_device *ofdev) -{ - struct mdio_gpio_platform_data *pdata; - struct mii_bus *new_bus; - int ret; - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - ret = of_get_gpio(ofdev->dev.of_node, 0); - if (ret < 0) - goto out_free; - pdata->mdc = ret; - - ret = of_get_gpio(ofdev->dev.of_node, 1); - if (ret < 0) - goto out_free; - pdata->mdio = ret; - - new_bus = mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); - if (!new_bus) - goto out_free; - - ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); - if (ret) - mdio_gpio_bus_deinit(&ofdev->dev); - - return ret; - -out_free: - kfree(pdata); - return -ENODEV; -} - -static int __devexit mdio_ofgpio_remove(struct platform_device *ofdev) -{ - mdio_gpio_bus_destroy(&ofdev->dev); - kfree(ofdev->dev.platform_data); - - return 0; -} - -static struct of_device_id mdio_ofgpio_match[] = { - { - .compatible = "virtual,mdio-gpio", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); - -static struct platform_driver mdio_ofgpio_driver = { - .driver = { - .name = "mdio-ofgpio", - .owner = THIS_MODULE, - .of_match_table = mdio_ofgpio_match, - }, - .probe = mdio_ofgpio_probe, - .remove = __devexit_p(mdio_ofgpio_remove), -}; - -static inline int __init mdio_ofgpio_init(void) -{ - return platform_driver_register(&mdio_ofgpio_driver); -} - -static inline void mdio_ofgpio_exit(void) -{ - platform_driver_unregister(&mdio_ofgpio_driver); -} -#else -static inline int __init mdio_ofgpio_init(void) { return 0; } -static inline void mdio_ofgpio_exit(void) { } -#endif /* CONFIG_OF_GPIO */ - -static struct platform_driver mdio_gpio_driver = { - .probe = mdio_gpio_probe, - .remove = __devexit_p(mdio_gpio_remove), - .driver = { - .name = "mdio-gpio", - .owner = THIS_MODULE, - }, -}; - -static int __init mdio_gpio_init(void) -{ - int ret; - - ret = mdio_ofgpio_init(); - if (ret) - return ret; - - ret = platform_driver_register(&mdio_gpio_driver); - if (ret) - mdio_ofgpio_exit(); - - return ret; -} -module_init(mdio_gpio_init); - -static void __exit mdio_gpio_exit(void) -{ - platform_driver_unregister(&mdio_gpio_driver); - mdio_ofgpio_exit(); -} -module_exit(mdio_gpio_exit); - -MODULE_ALIAS("platform:mdio-gpio"); -MODULE_AUTHOR("Laurent Pinchart, Paulius Zaleckas"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Generic driver for MDIO bus emulation using GPIO"); diff --git a/ANDROID_3.4.5/drivers/net/phy/mdio-octeon.c b/ANDROID_3.4.5/drivers/net/phy/mdio-octeon.c deleted file mode 100644 index 826d961f..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/mdio-octeon.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2009 Cavium Networks - */ - -#include <linux/gfp.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/phy.h> - -#include <asm/octeon/octeon.h> -#include <asm/octeon/cvmx-smix-defs.h> - -#define DRV_VERSION "1.0" -#define DRV_DESCRIPTION "Cavium Networks Octeon SMI/MDIO driver" - -struct octeon_mdiobus { - struct mii_bus *mii_bus; - int unit; - int phy_irq[PHY_MAX_ADDR]; -}; - -static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) -{ - struct octeon_mdiobus *p = bus->priv; - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_rd_dat smi_rd; - int timeout = 1000; - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */ - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = regnum; - cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64); - - do { - /* - * Wait 1000 clocks so we don't saturate the RSL bus - * doing reads. - */ - cvmx_wait(1000); - smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(p->unit)); - } while (smi_rd.s.pending && --timeout); - - if (smi_rd.s.val) - return smi_rd.s.dat; - else - return -EIO; -} - -static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id, - int regnum, u16 val) -{ - struct octeon_mdiobus *p = bus->priv; - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_wr_dat smi_wr; - int timeout = 1000; - - smi_wr.u64 = 0; - smi_wr.s.dat = val; - cvmx_write_csr(CVMX_SMIX_WR_DAT(p->unit), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */ - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = regnum; - cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64); - - do { - /* - * Wait 1000 clocks so we don't saturate the RSL bus - * doing reads. - */ - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(p->unit)); - } while (smi_wr.s.pending && --timeout); - - if (timeout <= 0) - return -EIO; - - return 0; -} - -static int __devinit octeon_mdiobus_probe(struct platform_device *pdev) -{ - struct octeon_mdiobus *bus; - union cvmx_smix_en smi_en; - int i; - int err = -ENOENT; - - bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); - if (!bus) - return -ENOMEM; - - /* The platform_device id is our unit number. */ - bus->unit = pdev->id; - - bus->mii_bus = mdiobus_alloc(); - - if (!bus->mii_bus) - goto err; - - smi_en.u64 = 0; - smi_en.s.en = 1; - cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64); - - /* - * Standard Octeon evaluation boards don't support phy - * interrupts, we need to poll. - */ - for (i = 0; i < PHY_MAX_ADDR; i++) - bus->phy_irq[i] = PHY_POLL; - - bus->mii_bus->priv = bus; - bus->mii_bus->irq = bus->phy_irq; - bus->mii_bus->name = "mdio-octeon"; - snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", - bus->mii_bus->name, bus->unit); - bus->mii_bus->parent = &pdev->dev; - - bus->mii_bus->read = octeon_mdiobus_read; - bus->mii_bus->write = octeon_mdiobus_write; - - dev_set_drvdata(&pdev->dev, bus); - - err = mdiobus_register(bus->mii_bus); - if (err) - goto err_register; - - dev_info(&pdev->dev, "Version " DRV_VERSION "\n"); - - return 0; -err_register: - mdiobus_free(bus->mii_bus); - -err: - devm_kfree(&pdev->dev, bus); - smi_en.u64 = 0; - cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64); - return err; -} - -static int __devexit octeon_mdiobus_remove(struct platform_device *pdev) -{ - struct octeon_mdiobus *bus; - union cvmx_smix_en smi_en; - - bus = dev_get_drvdata(&pdev->dev); - - mdiobus_unregister(bus->mii_bus); - mdiobus_free(bus->mii_bus); - smi_en.u64 = 0; - cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64); - return 0; -} - -static struct platform_driver octeon_mdiobus_driver = { - .driver = { - .name = "mdio-octeon", - .owner = THIS_MODULE, - }, - .probe = octeon_mdiobus_probe, - .remove = __devexit_p(octeon_mdiobus_remove), -}; - -void octeon_mdiobus_force_mod_depencency(void) -{ - /* Let ethernet drivers force us to be loaded. */ -} -EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency); - -static int __init octeon_mdiobus_mod_init(void) -{ - return platform_driver_register(&octeon_mdiobus_driver); -} - -static void __exit octeon_mdiobus_mod_exit(void) -{ - platform_driver_unregister(&octeon_mdiobus_driver); -} - -module_init(octeon_mdiobus_mod_init); -module_exit(octeon_mdiobus_mod_exit); - -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR("David Daney"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/net/phy/mdio_bus.c b/ANDROID_3.4.5/drivers/net/phy/mdio_bus.c deleted file mode 100644 index 8985cc62..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/mdio_bus.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * drivers/net/phy/mdio_bus.c - * - * MDIO Bus interface - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -/** - * mdiobus_alloc_size - allocate a mii_bus structure - * @size: extra amount of memory to allocate for private storage. - * If non-zero, then bus->priv is points to that memory. - * - * Description: called by a bus driver to allocate an mii_bus - * structure to fill in. - */ -struct mii_bus *mdiobus_alloc_size(size_t size) -{ - struct mii_bus *bus; - size_t aligned_size = ALIGN(sizeof(*bus), NETDEV_ALIGN); - size_t alloc_size; - - /* If we alloc extra space, it should be aligned */ - if (size) - alloc_size = aligned_size + size; - else - alloc_size = sizeof(*bus); - - bus = kzalloc(alloc_size, GFP_KERNEL); - if (bus) { - bus->state = MDIOBUS_ALLOCATED; - if (size) - bus->priv = (void *)bus + aligned_size; - } - - return bus; -} -EXPORT_SYMBOL(mdiobus_alloc_size); - -/** - * mdiobus_release - mii_bus device release callback - * @d: the target struct device that contains the mii_bus - * - * Description: called when the last reference to an mii_bus is - * dropped, to free the underlying memory. - */ -static void mdiobus_release(struct device *d) -{ - struct mii_bus *bus = to_mii_bus(d); - BUG_ON(bus->state != MDIOBUS_RELEASED && - /* for compatibility with error handling in drivers */ - bus->state != MDIOBUS_ALLOCATED); - kfree(bus); -} - -static struct class mdio_bus_class = { - .name = "mdio_bus", - .dev_release = mdiobus_release, -}; - -/** - * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus - * @bus: target mii_bus - * - * Description: Called by a bus driver to bring up all the PHYs - * on a given bus, and attach them to the bus. - * - * Returns 0 on success or < 0 on error. - */ -int mdiobus_register(struct mii_bus *bus) -{ - int i, err; - - if (NULL == bus || NULL == bus->name || - NULL == bus->read || - NULL == bus->write) - return -EINVAL; - - BUG_ON(bus->state != MDIOBUS_ALLOCATED && - bus->state != MDIOBUS_UNREGISTERED); - - bus->dev.parent = bus->parent; - bus->dev.class = &mdio_bus_class; - bus->dev.groups = NULL; - dev_set_name(&bus->dev, "%s", bus->id); - - err = device_register(&bus->dev); - if (err) { - printk(KERN_ERR "mii_bus %s failed to register\n", bus->id); - return -EINVAL; - } - - mutex_init(&bus->mdio_lock); - - if (bus->reset) - bus->reset(bus); - - for (i = 0; i < PHY_MAX_ADDR; i++) { - if ((bus->phy_mask & (1 << i)) == 0) { - struct phy_device *phydev; - - phydev = mdiobus_scan(bus, i); - if (IS_ERR(phydev)) { - err = PTR_ERR(phydev); - goto error; - } - } - } - - bus->state = MDIOBUS_REGISTERED; - pr_info("%s: probed\n", bus->name); - return 0; - -error: - while (--i >= 0) { - if (bus->phy_map[i]) - device_unregister(&bus->phy_map[i]->dev); - } - device_del(&bus->dev); - return err; -} -EXPORT_SYMBOL(mdiobus_register); - -void mdiobus_unregister(struct mii_bus *bus) -{ - int i; - - BUG_ON(bus->state != MDIOBUS_REGISTERED); - bus->state = MDIOBUS_UNREGISTERED; - - device_del(&bus->dev); - for (i = 0; i < PHY_MAX_ADDR; i++) { - if (bus->phy_map[i]) - device_unregister(&bus->phy_map[i]->dev); - bus->phy_map[i] = NULL; - } -} -EXPORT_SYMBOL(mdiobus_unregister); - -/** - * mdiobus_free - free a struct mii_bus - * @bus: mii_bus to free - * - * This function releases the reference to the underlying device - * object in the mii_bus. If this is the last reference, the mii_bus - * will be freed. - */ -void mdiobus_free(struct mii_bus *bus) -{ - /* - * For compatibility with error handling in drivers. - */ - if (bus->state == MDIOBUS_ALLOCATED) { - kfree(bus); - return; - } - - BUG_ON(bus->state != MDIOBUS_UNREGISTERED); - bus->state = MDIOBUS_RELEASED; - - put_device(&bus->dev); -} -EXPORT_SYMBOL(mdiobus_free); - -struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) -{ - struct phy_device *phydev; - int err; - - phydev = get_phy_device(bus, addr); - if (IS_ERR(phydev) || phydev == NULL) - return phydev; - - err = phy_device_register(phydev); - if (err) { - phy_device_free(phydev); - return NULL; - } - - return phydev; -} -EXPORT_SYMBOL(mdiobus_scan); - -/** - * mdiobus_read - Convenience function for reading a given MII mgmt register - * @bus: the mii_bus struct - * @addr: the phy address - * @regnum: register number to read - * - * NOTE: MUST NOT be called from interrupt context, - * because the bus read/write functions may wait for an interrupt - * to conclude the operation. - */ -int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum) -{ - int retval; - - BUG_ON(in_interrupt()); - - mutex_lock(&bus->mdio_lock); - retval = bus->read(bus, addr, regnum); - mutex_unlock(&bus->mdio_lock); - - return retval; -} -EXPORT_SYMBOL(mdiobus_read); - -/** - * mdiobus_write - Convenience function for writing a given MII mgmt register - * @bus: the mii_bus struct - * @addr: the phy address - * @regnum: register number to write - * @val: value to write to @regnum - * - * NOTE: MUST NOT be called from interrupt context, - * because the bus read/write functions may wait for an interrupt - * to conclude the operation. - */ -int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val) -{ - int err; - - BUG_ON(in_interrupt()); - - mutex_lock(&bus->mdio_lock); - err = bus->write(bus, addr, regnum, val); - mutex_unlock(&bus->mdio_lock); - - return err; -} -EXPORT_SYMBOL(mdiobus_write); - -/** - * mdio_bus_match - determine if given PHY driver supports the given PHY device - * @dev: target PHY device - * @drv: given PHY driver - * - * Description: Given a PHY device, and a PHY driver, return 1 if - * the driver supports the device. Otherwise, return 0. - */ -static int mdio_bus_match(struct device *dev, struct device_driver *drv) -{ - struct phy_device *phydev = to_phy_device(dev); - struct phy_driver *phydrv = to_phy_driver(drv); - - return ((phydrv->phy_id & phydrv->phy_id_mask) == - (phydev->phy_id & phydrv->phy_id_mask)); -} - -#ifdef CONFIG_PM - -static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) -{ - struct device_driver *drv = phydev->dev.driver; - struct phy_driver *phydrv = to_phy_driver(drv); - struct net_device *netdev = phydev->attached_dev; - - if (!drv || !phydrv->suspend) - return false; - - /* PHY not attached? May suspend. */ - if (!netdev) - return true; - - /* - * Don't suspend PHY if the attched netdev parent may wakeup. - * The parent may point to a PCI device, as in tg3 driver. - */ - if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent)) - return false; - - /* - * Also don't suspend PHY if the netdev itself may wakeup. This - * is the case for devices w/o underlaying pwr. mgmt. aware bus, - * e.g. SoC devices. - */ - if (device_may_wakeup(&netdev->dev)) - return false; - - return true; -} - -static int mdio_bus_suspend(struct device *dev) -{ - struct phy_driver *phydrv = to_phy_driver(dev->driver); - struct phy_device *phydev = to_phy_device(dev); - - /* - * We must stop the state machine manually, otherwise it stops out of - * control, possibly with the phydev->lock held. Upon resume, netdev - * may call phy routines that try to grab the same lock, and that may - * lead to a deadlock. - */ - if (phydev->attached_dev && phydev->adjust_link) - phy_stop_machine(phydev); - - if (!mdio_bus_phy_may_suspend(phydev)) - return 0; - - return phydrv->suspend(phydev); -} - -static int mdio_bus_resume(struct device *dev) -{ - struct phy_driver *phydrv = to_phy_driver(dev->driver); - struct phy_device *phydev = to_phy_device(dev); - int ret; - - if (!mdio_bus_phy_may_suspend(phydev)) - goto no_resume; - - ret = phydrv->resume(phydev); - if (ret < 0) - return ret; - -no_resume: - if (phydev->attached_dev && phydev->adjust_link) - phy_start_machine(phydev, NULL); - - return 0; -} - -static int mdio_bus_restore(struct device *dev) -{ - struct phy_device *phydev = to_phy_device(dev); - struct net_device *netdev = phydev->attached_dev; - int ret; - - if (!netdev) - return 0; - - ret = phy_init_hw(phydev); - if (ret < 0) - return ret; - - /* The PHY needs to renegotiate. */ - phydev->link = 0; - phydev->state = PHY_UP; - - phy_start_machine(phydev, NULL); - - return 0; -} - -static struct dev_pm_ops mdio_bus_pm_ops = { - .suspend = mdio_bus_suspend, - .resume = mdio_bus_resume, - .freeze = mdio_bus_suspend, - .thaw = mdio_bus_resume, - .restore = mdio_bus_restore, -}; - -#define MDIO_BUS_PM_OPS (&mdio_bus_pm_ops) - -#else - -#define MDIO_BUS_PM_OPS NULL - -#endif /* CONFIG_PM */ - -struct bus_type mdio_bus_type = { - .name = "mdio_bus", - .match = mdio_bus_match, - .pm = MDIO_BUS_PM_OPS, -}; -EXPORT_SYMBOL(mdio_bus_type); - -int __init mdio_bus_init(void) -{ - int ret; - - ret = class_register(&mdio_bus_class); - if (!ret) { - ret = bus_register(&mdio_bus_type); - if (ret) - class_unregister(&mdio_bus_class); - } - - return ret; -} - -void mdio_bus_exit(void) -{ - class_unregister(&mdio_bus_class); - bus_unregister(&mdio_bus_type); -} diff --git a/ANDROID_3.4.5/drivers/net/phy/micrel.c b/ANDROID_3.4.5/drivers/net/phy/micrel.c deleted file mode 100644 index 590f902d..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/micrel.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * drivers/net/phy/micrel.c - * - * Driver for Micrel PHYs - * - * Author: David J. Choi - * - * Copyright (c) 2010 Micrel, 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. - * - * Support : ksz9021 1000/100/10 phy from Micrel - * ks8001, ks8737, ks8721, ks8041, ks8051 100/10 phy - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/phy.h> -#include <linux/micrel_phy.h> - -/* general Interrupt control/status reg in vendor specific block. */ -#define MII_KSZPHY_INTCS 0x1B -#define KSZPHY_INTCS_JABBER (1 << 15) -#define KSZPHY_INTCS_RECEIVE_ERR (1 << 14) -#define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13) -#define KSZPHY_INTCS_PARELLEL (1 << 12) -#define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11) -#define KSZPHY_INTCS_LINK_DOWN (1 << 10) -#define KSZPHY_INTCS_REMOTE_FAULT (1 << 9) -#define KSZPHY_INTCS_LINK_UP (1 << 8) -#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\ - KSZPHY_INTCS_LINK_DOWN) - -/* general PHY control reg in vendor specific block. */ -#define MII_KSZPHY_CTRL 0x1F -/* bitmap of PHY register to set interrupt mode */ -#define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9) -#define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14) -#define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) -#define KSZ8051_RMII_50MHZ_CLK (1 << 7) - -static int kszphy_ack_interrupt(struct phy_device *phydev) -{ - /* bit[7..0] int status, which is a read and clear register. */ - int rc; - - rc = phy_read(phydev, MII_KSZPHY_INTCS); - - return (rc < 0) ? rc : 0; -} - -static int kszphy_set_interrupt(struct phy_device *phydev) -{ - int temp; - temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ? - KSZPHY_INTCS_ALL : 0; - return phy_write(phydev, MII_KSZPHY_INTCS, temp); -} - -static int kszphy_config_intr(struct phy_device *phydev) -{ - int temp, rc; - - /* set the interrupt pin active low */ - temp = phy_read(phydev, MII_KSZPHY_CTRL); - temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; - phy_write(phydev, MII_KSZPHY_CTRL, temp); - rc = kszphy_set_interrupt(phydev); - return rc < 0 ? rc : 0; -} - -static int ksz9021_config_intr(struct phy_device *phydev) -{ - int temp, rc; - - /* set the interrupt pin active low */ - temp = phy_read(phydev, MII_KSZPHY_CTRL); - temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; - phy_write(phydev, MII_KSZPHY_CTRL, temp); - rc = kszphy_set_interrupt(phydev); - return rc < 0 ? rc : 0; -} - -static int ks8737_config_intr(struct phy_device *phydev) -{ - int temp, rc; - - /* set the interrupt pin active low */ - temp = phy_read(phydev, MII_KSZPHY_CTRL); - temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH; - phy_write(phydev, MII_KSZPHY_CTRL, temp); - rc = kszphy_set_interrupt(phydev); - return rc < 0 ? rc : 0; -} - -static int kszphy_config_init(struct phy_device *phydev) -{ - return 0; -} - -static int ks8051_config_init(struct phy_device *phydev) -{ - int regval; - - if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { - regval = phy_read(phydev, MII_KSZPHY_CTRL); - regval |= KSZ8051_RMII_50MHZ_CLK; - phy_write(phydev, MII_KSZPHY_CTRL, regval); - } - - return 0; -} - -static struct phy_driver ks8737_driver = { - .phy_id = PHY_ID_KS8737, - .phy_id_mask = 0x00fffff0, - .name = "Micrel KS8737", - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = kszphy_ack_interrupt, - .config_intr = ks8737_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver ks8041_driver = { - .phy_id = PHY_ID_KS8041, - .phy_id_mask = 0x00fffff0, - .name = "Micrel KS8041", - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = kszphy_ack_interrupt, - .config_intr = kszphy_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver ks8051_driver = { - .phy_id = PHY_ID_KS8051, - .phy_id_mask = 0x00fffff0, - .name = "Micrel KS8051", - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = ks8051_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = kszphy_ack_interrupt, - .config_intr = kszphy_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver ks8001_driver = { - .phy_id = PHY_ID_KS8001, - .name = "Micrel KS8001 or KS8721", - .phy_id_mask = 0x00fffff0, - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = kszphy_ack_interrupt, - .config_intr = kszphy_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static struct phy_driver ksz9021_driver = { - .phy_id = PHY_ID_KSZ9021, - .phy_id_mask = 0x000fff10, - .name = "Micrel KSZ9021 Gigabit PHY", - .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = kszphy_ack_interrupt, - .config_intr = ksz9021_config_intr, - .driver = { .owner = THIS_MODULE, }, -}; - -static int __init ksphy_init(void) -{ - int ret; - - ret = phy_driver_register(&ks8001_driver); - if (ret) - goto err1; - - ret = phy_driver_register(&ksz9021_driver); - if (ret) - goto err2; - - ret = phy_driver_register(&ks8737_driver); - if (ret) - goto err3; - ret = phy_driver_register(&ks8041_driver); - if (ret) - goto err4; - ret = phy_driver_register(&ks8051_driver); - if (ret) - goto err5; - - return 0; - -err5: - phy_driver_unregister(&ks8041_driver); -err4: - phy_driver_unregister(&ks8737_driver); -err3: - phy_driver_unregister(&ksz9021_driver); -err2: - phy_driver_unregister(&ks8001_driver); -err1: - return ret; -} - -static void __exit ksphy_exit(void) -{ - phy_driver_unregister(&ks8001_driver); - phy_driver_unregister(&ks8737_driver); - phy_driver_unregister(&ksz9021_driver); - phy_driver_unregister(&ks8041_driver); - phy_driver_unregister(&ks8051_driver); -} - -module_init(ksphy_init); -module_exit(ksphy_exit); - -MODULE_DESCRIPTION("Micrel PHY driver"); -MODULE_AUTHOR("David J. Choi"); -MODULE_LICENSE("GPL"); - -static struct mdio_device_id __maybe_unused micrel_tbl[] = { - { PHY_ID_KSZ9021, 0x000fff10 }, - { PHY_ID_KS8001, 0x00fffff0 }, - { PHY_ID_KS8737, 0x00fffff0 }, - { PHY_ID_KS8041, 0x00fffff0 }, - { PHY_ID_KS8051, 0x00fffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, micrel_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/national.c b/ANDROID_3.4.5/drivers/net/phy/national.c deleted file mode 100644 index 04bb8fcc..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/national.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * drivers/net/phy/national.c - * - * Driver for National Semiconductor PHYs - * - * Author: Stuart Menefy <stuart.menefy@st.com> - * Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com> - * - * Copyright (c) 2008 STMicroelectronics Limited - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> -#include <linux/netdevice.h> - -/* DP83865 phy identifier values */ -#define DP83865_PHY_ID 0x20005c7a - -#define DP83865_INT_STATUS 0x14 -#define DP83865_INT_MASK 0x15 -#define DP83865_INT_CLEAR 0x17 - -#define DP83865_INT_REMOTE_FAULT 0x0008 -#define DP83865_INT_ANE_COMPLETED 0x0010 -#define DP83865_INT_LINK_CHANGE 0xe000 -#define DP83865_INT_MASK_DEFAULT (DP83865_INT_REMOTE_FAULT | \ - DP83865_INT_ANE_COMPLETED | \ - DP83865_INT_LINK_CHANGE) - -/* Advanced proprietary configuration */ -#define NS_EXP_MEM_CTL 0x16 -#define NS_EXP_MEM_DATA 0x1d -#define NS_EXP_MEM_ADD 0x1e - -#define LED_CTRL_REG 0x13 -#define AN_FALLBACK_AN 0x0001 -#define AN_FALLBACK_CRC 0x0002 -#define AN_FALLBACK_IE 0x0004 -#define ALL_FALLBACK_ON (AN_FALLBACK_AN | AN_FALLBACK_CRC | AN_FALLBACK_IE) - -enum hdx_loopback { - hdx_loopback_on = 0, - hdx_loopback_off = 1, -}; - -static u8 ns_exp_read(struct phy_device *phydev, u16 reg) -{ - phy_write(phydev, NS_EXP_MEM_ADD, reg); - return phy_read(phydev, NS_EXP_MEM_DATA); -} - -static void ns_exp_write(struct phy_device *phydev, u16 reg, u8 data) -{ - phy_write(phydev, NS_EXP_MEM_ADD, reg); - phy_write(phydev, NS_EXP_MEM_DATA, data); -} - -static int ns_config_intr(struct phy_device *phydev) -{ - int err; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, DP83865_INT_MASK, - DP83865_INT_MASK_DEFAULT); - else - err = phy_write(phydev, DP83865_INT_MASK, 0); - - return err; -} - -static int ns_ack_interrupt(struct phy_device *phydev) -{ - int ret = phy_read(phydev, DP83865_INT_STATUS); - if (ret < 0) - return ret; - - /* Clear the interrupt status bit by writing a “1” - * to the corresponding bit in INT_CLEAR (2:0 are reserved) */ - ret = phy_write(phydev, DP83865_INT_CLEAR, ret & ~0x7); - - return ret; -} - -static void ns_giga_speed_fallback(struct phy_device *phydev, int mode) -{ - int bmcr = phy_read(phydev, MII_BMCR); - - phy_write(phydev, MII_BMCR, (bmcr | BMCR_PDOWN)); - - /* Enable 8 bit expended memory read/write (no auto increment) */ - phy_write(phydev, NS_EXP_MEM_CTL, 0); - phy_write(phydev, NS_EXP_MEM_ADD, 0x1C0); - phy_write(phydev, NS_EXP_MEM_DATA, 0x0008); - phy_write(phydev, MII_BMCR, (bmcr & ~BMCR_PDOWN)); - phy_write(phydev, LED_CTRL_REG, mode); -} - -static void ns_10_base_t_hdx_loopack(struct phy_device *phydev, int disable) -{ - if (disable) - ns_exp_write(phydev, 0x1c0, ns_exp_read(phydev, 0x1c0) | 1); - else - ns_exp_write(phydev, 0x1c0, - ns_exp_read(phydev, 0x1c0) & 0xfffe); - - printk(KERN_DEBUG "DP83865 PHY: 10BASE-T HDX loopback %s\n", - (ns_exp_read(phydev, 0x1c0) & 0x0001) ? "off" : "on"); -} - -static int ns_config_init(struct phy_device *phydev) -{ - ns_giga_speed_fallback(phydev, ALL_FALLBACK_ON); - /* In the latest MAC or switches design, the 10 Mbps loopback - is desired to be turned off. */ - ns_10_base_t_hdx_loopack(phydev, hdx_loopback_off); - return ns_ack_interrupt(phydev); -} - -static struct phy_driver dp83865_driver = { - .phy_id = DP83865_PHY_ID, - .phy_id_mask = 0xfffffff0, - .name = "NatSemi DP83865", - .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_INTERRUPT, - .config_init = ns_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = ns_ack_interrupt, - .config_intr = ns_config_intr, - .driver = {.owner = THIS_MODULE,} -}; - -static int __init ns_init(void) -{ - return phy_driver_register(&dp83865_driver); -} - -static void __exit ns_exit(void) -{ - phy_driver_unregister(&dp83865_driver); -} - -MODULE_DESCRIPTION("NatSemi PHY driver"); -MODULE_AUTHOR("Stuart Menefy"); -MODULE_LICENSE("GPL"); - -module_init(ns_init); -module_exit(ns_exit); - -static struct mdio_device_id __maybe_unused ns_tbl[] = { - { DP83865_PHY_ID, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, ns_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/phy.c b/ANDROID_3.4.5/drivers/net/phy/phy.c deleted file mode 100644 index 3cbda085..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/phy.c +++ /dev/null @@ -1,970 +0,0 @@ -/* - * drivers/net/phy/phy.c - * - * Framework for configuring and reading PHY devices - * Based on code in sungem_phy.c and gianfar_phy.c - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, Inc. - * Copyright (c) 2006, 2007 Maciej W. Rozycki - * - * 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> -#include <linux/timer.h> -#include <linux/workqueue.h> - -#include <linux/atomic.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -/** - * phy_print_status - Convenience function to print out the current phy status - * @phydev: the phy_device struct - */ -void phy_print_status(struct phy_device *phydev) -{ - pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev), - phydev->link ? "Up" : "Down"); - if (phydev->link) - printk(KERN_CONT " - %d/%s", phydev->speed, - DUPLEX_FULL == phydev->duplex ? - "Full" : "Half"); - - printk(KERN_CONT "\n"); -} -EXPORT_SYMBOL(phy_print_status); - - -/** - * phy_clear_interrupt - Ack the phy device's interrupt - * @phydev: the phy_device struct - * - * If the @phydev driver has an ack_interrupt function, call it to - * ack and clear the phy device's interrupt. - * - * Returns 0 on success on < 0 on error. - */ -static int phy_clear_interrupt(struct phy_device *phydev) -{ - int err = 0; - - if (phydev->drv->ack_interrupt) - err = phydev->drv->ack_interrupt(phydev); - - return err; -} - -/** - * phy_config_interrupt - configure the PHY device for the requested interrupts - * @phydev: the phy_device struct - * @interrupts: interrupt flags to configure for this @phydev - * - * Returns 0 on success on < 0 on error. - */ -static int phy_config_interrupt(struct phy_device *phydev, u32 interrupts) -{ - int err = 0; - - phydev->interrupts = interrupts; - if (phydev->drv->config_intr) - err = phydev->drv->config_intr(phydev); - - return err; -} - - -/** - * phy_aneg_done - return auto-negotiation status - * @phydev: target phy_device struct - * - * Description: Reads the status register and returns 0 either if - * auto-negotiation is incomplete, or if there was an error. - * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done. - */ -static inline int phy_aneg_done(struct phy_device *phydev) -{ - int retval; - - retval = phy_read(phydev, MII_BMSR); - - return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE); -} - -/* A structure for mapping a particular speed and duplex - * combination to a particular SUPPORTED and ADVERTISED value */ -struct phy_setting { - int speed; - int duplex; - u32 setting; -}; - -/* A mapping of all SUPPORTED settings to speed/duplex */ -static const struct phy_setting settings[] = { - { - .speed = 10000, - .duplex = DUPLEX_FULL, - .setting = SUPPORTED_10000baseT_Full, - }, - { - .speed = SPEED_1000, - .duplex = DUPLEX_FULL, - .setting = SUPPORTED_1000baseT_Full, - }, - { - .speed = SPEED_1000, - .duplex = DUPLEX_HALF, - .setting = SUPPORTED_1000baseT_Half, - }, - { - .speed = SPEED_100, - .duplex = DUPLEX_FULL, - .setting = SUPPORTED_100baseT_Full, - }, - { - .speed = SPEED_100, - .duplex = DUPLEX_HALF, - .setting = SUPPORTED_100baseT_Half, - }, - { - .speed = SPEED_10, - .duplex = DUPLEX_FULL, - .setting = SUPPORTED_10baseT_Full, - }, - { - .speed = SPEED_10, - .duplex = DUPLEX_HALF, - .setting = SUPPORTED_10baseT_Half, - }, -}; - -#define MAX_NUM_SETTINGS ARRAY_SIZE(settings) - -/** - * phy_find_setting - find a PHY settings array entry that matches speed & duplex - * @speed: speed to match - * @duplex: duplex to match - * - * Description: Searches the settings array for the setting which - * matches the desired speed and duplex, and returns the index - * of that setting. Returns the index of the last setting if - * none of the others match. - */ -static inline int phy_find_setting(int speed, int duplex) -{ - int idx = 0; - - while (idx < ARRAY_SIZE(settings) && - (settings[idx].speed != speed || - settings[idx].duplex != duplex)) - idx++; - - return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; -} - -/** - * phy_find_valid - find a PHY setting that matches the requested features mask - * @idx: The first index in settings[] to search - * @features: A mask of the valid settings - * - * Description: Returns the index of the first valid setting less - * than or equal to the one pointed to by idx, as determined by - * the mask in features. Returns the index of the last setting - * if nothing else matches. - */ -static inline int phy_find_valid(int idx, u32 features) -{ - while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) - idx++; - - return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; -} - -/** - * phy_sanitize_settings - make sure the PHY is set to supported speed and duplex - * @phydev: the target phy_device struct - * - * Description: Make sure the PHY is set to supported speeds and - * duplexes. Drop down by one in this order: 1000/FULL, - * 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF. - */ -static void phy_sanitize_settings(struct phy_device *phydev) -{ - u32 features = phydev->supported; - int idx; - - /* Sanitize settings based on PHY capabilities */ - if ((features & SUPPORTED_Autoneg) == 0) - phydev->autoneg = AUTONEG_DISABLE; - - idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex), - features); - - phydev->speed = settings[idx].speed; - phydev->duplex = settings[idx].duplex; -} - -/** - * phy_ethtool_sset - generic ethtool sset function, handles all the details - * @phydev: target phy_device struct - * @cmd: ethtool_cmd - * - * A few notes about parameter checking: - * - We don't set port or transceiver, so we don't care what they - * were set to. - * - phy_start_aneg() will make sure forced settings are sane, and - * choose the next best ones from the ones selected, so we don't - * care if ethtool tries to give us bad values. - */ -int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) -{ - u32 speed = ethtool_cmd_speed(cmd); - - if (cmd->phy_address != phydev->addr) - return -EINVAL; - - /* We make sure that we don't pass unsupported - * values in to the PHY */ - cmd->advertising &= phydev->supported; - - /* Verify the settings we care about. */ - if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) - return -EINVAL; - - if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0) - return -EINVAL; - - if (cmd->autoneg == AUTONEG_DISABLE && - ((speed != SPEED_1000 && - speed != SPEED_100 && - speed != SPEED_10) || - (cmd->duplex != DUPLEX_HALF && - cmd->duplex != DUPLEX_FULL))) - return -EINVAL; - - phydev->autoneg = cmd->autoneg; - - phydev->speed = speed; - - phydev->advertising = cmd->advertising; - - if (AUTONEG_ENABLE == cmd->autoneg) - phydev->advertising |= ADVERTISED_Autoneg; - else - phydev->advertising &= ~ADVERTISED_Autoneg; - - phydev->duplex = cmd->duplex; - - /* Restart the PHY */ - phy_start_aneg(phydev); - - return 0; -} -EXPORT_SYMBOL(phy_ethtool_sset); - -int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) -{ - cmd->supported = phydev->supported; - - cmd->advertising = phydev->advertising; - - ethtool_cmd_speed_set(cmd, phydev->speed); - cmd->duplex = phydev->duplex; - cmd->port = PORT_MII; - cmd->phy_address = phydev->addr; - cmd->transceiver = XCVR_EXTERNAL; - cmd->autoneg = phydev->autoneg; - - return 0; -} -EXPORT_SYMBOL(phy_ethtool_gset); - -/** - * phy_mii_ioctl - generic PHY MII ioctl interface - * @phydev: the phy_device struct - * @ifr: &struct ifreq for socket ioctl's - * @cmd: ioctl cmd to execute - * - * Note that this function is currently incompatible with the - * PHYCONTROL layer. It changes registers without regard to - * current state. Use at own risk. - */ -int phy_mii_ioctl(struct phy_device *phydev, - struct ifreq *ifr, int cmd) -{ - struct mii_ioctl_data *mii_data = if_mii(ifr); - u16 val = mii_data->val_in; - - switch (cmd) { - case SIOCGMIIPHY: - mii_data->phy_id = phydev->addr; - /* fall through */ - - case SIOCGMIIREG: - mii_data->val_out = mdiobus_read(phydev->bus, mii_data->phy_id, - mii_data->reg_num); - break; - - case SIOCSMIIREG: - if (mii_data->phy_id == phydev->addr) { - switch(mii_data->reg_num) { - case MII_BMCR: - if ((val & (BMCR_RESET|BMCR_ANENABLE)) == 0) - phydev->autoneg = AUTONEG_DISABLE; - else - phydev->autoneg = AUTONEG_ENABLE; - if ((!phydev->autoneg) && (val & BMCR_FULLDPLX)) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - if ((!phydev->autoneg) && - (val & BMCR_SPEED1000)) - phydev->speed = SPEED_1000; - else if ((!phydev->autoneg) && - (val & BMCR_SPEED100)) - phydev->speed = SPEED_100; - break; - case MII_ADVERTISE: - phydev->advertising = val; - break; - default: - /* do nothing */ - break; - } - } - - mdiobus_write(phydev->bus, mii_data->phy_id, - mii_data->reg_num, val); - - if (mii_data->reg_num == MII_BMCR && - val & BMCR_RESET && - phydev->drv->config_init) { - phy_scan_fixups(phydev); - phydev->drv->config_init(phydev); - } - break; - - case SIOCSHWTSTAMP: - if (phydev->drv->hwtstamp) - return phydev->drv->hwtstamp(phydev, ifr); - /* fall through */ - - default: - return -EOPNOTSUPP; - } - - return 0; -} -EXPORT_SYMBOL(phy_mii_ioctl); - -/** - * phy_start_aneg - start auto-negotiation for this PHY device - * @phydev: the phy_device struct - * - * Description: Sanitizes the settings (if we're not autonegotiating - * them), and then calls the driver's config_aneg function. - * If the PHYCONTROL Layer is operating, we change the state to - * reflect the beginning of Auto-negotiation or forcing. - */ -int phy_start_aneg(struct phy_device *phydev) -{ - int err; - - mutex_lock(&phydev->lock); - - if (AUTONEG_DISABLE == phydev->autoneg) - phy_sanitize_settings(phydev); - - err = phydev->drv->config_aneg(phydev); - - if (err < 0) - goto out_unlock; - - if (phydev->state != PHY_HALTED) { - if (AUTONEG_ENABLE == phydev->autoneg) { - phydev->state = PHY_AN; - phydev->link_timeout = PHY_AN_TIMEOUT; - } else { - phydev->state = PHY_FORCING; - phydev->link_timeout = PHY_FORCE_TIMEOUT; - } - } - -out_unlock: - mutex_unlock(&phydev->lock); - return err; -} -EXPORT_SYMBOL(phy_start_aneg); - - -static void phy_change(struct work_struct *work); - -/** - * phy_start_machine - start PHY state machine tracking - * @phydev: the phy_device struct - * @handler: callback function for state change notifications - * - * Description: The PHY infrastructure can run a state machine - * which tracks whether the PHY is starting up, negotiating, - * etc. This function starts the timer which tracks the state - * of the PHY. If you want to be notified when the state changes, - * pass in the callback @handler, otherwise, pass NULL. If you - * want to maintain your own state machine, do not call this - * function. - */ -void phy_start_machine(struct phy_device *phydev, - void (*handler)(struct net_device *)) -{ - phydev->adjust_state = handler; - - schedule_delayed_work(&phydev->state_queue, HZ); -} - -/** - * phy_stop_machine - stop the PHY state machine tracking - * @phydev: target phy_device struct - * - * Description: Stops the state machine timer, sets the state to UP - * (unless it wasn't up yet). This function must be called BEFORE - * phy_detach. - */ -void phy_stop_machine(struct phy_device *phydev) -{ - cancel_delayed_work_sync(&phydev->state_queue); - - mutex_lock(&phydev->lock); - if (phydev->state > PHY_UP) - phydev->state = PHY_UP; - mutex_unlock(&phydev->lock); - - phydev->adjust_state = NULL; -} - -/** - * phy_force_reduction - reduce PHY speed/duplex settings by one step - * @phydev: target phy_device struct - * - * Description: Reduces the speed/duplex settings by one notch, - * in this order-- - * 1000/FULL, 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF. - * The function bottoms out at 10/HALF. - */ -static void phy_force_reduction(struct phy_device *phydev) -{ - int idx; - - idx = phy_find_setting(phydev->speed, phydev->duplex); - - idx++; - - idx = phy_find_valid(idx, phydev->supported); - - phydev->speed = settings[idx].speed; - phydev->duplex = settings[idx].duplex; - - pr_info("Trying %d/%s\n", phydev->speed, - DUPLEX_FULL == phydev->duplex ? - "FULL" : "HALF"); -} - - -/** - * phy_error - enter HALTED state for this PHY device - * @phydev: target phy_device struct - * - * Moves the PHY to the HALTED state in response to a read - * or write error, and tells the controller the link is down. - * Must not be called from interrupt context, or while the - * phydev->lock is held. - */ -static void phy_error(struct phy_device *phydev) -{ - mutex_lock(&phydev->lock); - phydev->state = PHY_HALTED; - mutex_unlock(&phydev->lock); -} - -/** - * phy_interrupt - PHY interrupt handler - * @irq: interrupt line - * @phy_dat: phy_device pointer - * - * Description: When a PHY interrupt occurs, the handler disables - * interrupts, and schedules a work task to clear the interrupt. - */ -static irqreturn_t phy_interrupt(int irq, void *phy_dat) -{ - struct phy_device *phydev = phy_dat; - - if (PHY_HALTED == phydev->state) - return IRQ_NONE; /* It can't be ours. */ - - /* The MDIO bus is not allowed to be written in interrupt - * context, so we need to disable the irq here. A work - * queue will write the PHY to disable and clear the - * interrupt, and then reenable the irq line. */ - disable_irq_nosync(irq); - atomic_inc(&phydev->irq_disable); - - schedule_work(&phydev->phy_queue); - - return IRQ_HANDLED; -} - -/** - * phy_enable_interrupts - Enable the interrupts from the PHY side - * @phydev: target phy_device struct - */ -static int phy_enable_interrupts(struct phy_device *phydev) -{ - int err; - - err = phy_clear_interrupt(phydev); - - if (err < 0) - return err; - - err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); - - return err; -} - -/** - * phy_disable_interrupts - Disable the PHY interrupts from the PHY side - * @phydev: target phy_device struct - */ -static int phy_disable_interrupts(struct phy_device *phydev) -{ - int err; - - /* Disable PHY interrupts */ - err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); - - if (err) - goto phy_err; - - /* Clear the interrupt */ - err = phy_clear_interrupt(phydev); - - if (err) - goto phy_err; - - return 0; - -phy_err: - phy_error(phydev); - - return err; -} - -/** - * phy_start_interrupts - request and enable interrupts for a PHY device - * @phydev: target phy_device struct - * - * Description: Request the interrupt for the given PHY. - * If this fails, then we set irq to PHY_POLL. - * Otherwise, we enable the interrupts in the PHY. - * This should only be called with a valid IRQ number. - * Returns 0 on success or < 0 on error. - */ -int phy_start_interrupts(struct phy_device *phydev) -{ - int err = 0; - - INIT_WORK(&phydev->phy_queue, phy_change); - - atomic_set(&phydev->irq_disable, 0); - if (request_irq(phydev->irq, phy_interrupt, - IRQF_SHARED, - "phy_interrupt", - phydev) < 0) { - printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n", - phydev->bus->name, - phydev->irq); - phydev->irq = PHY_POLL; - return 0; - } - - err = phy_enable_interrupts(phydev); - - return err; -} -EXPORT_SYMBOL(phy_start_interrupts); - -/** - * phy_stop_interrupts - disable interrupts from a PHY device - * @phydev: target phy_device struct - */ -int phy_stop_interrupts(struct phy_device *phydev) -{ - int err; - - err = phy_disable_interrupts(phydev); - - if (err) - phy_error(phydev); - - free_irq(phydev->irq, phydev); - - /* - * Cannot call flush_scheduled_work() here as desired because - * of rtnl_lock(), but we do not really care about what would - * be done, except from enable_irq(), so cancel any work - * possibly pending and take care of the matter below. - */ - cancel_work_sync(&phydev->phy_queue); - /* - * If work indeed has been cancelled, disable_irq() will have - * been left unbalanced from phy_interrupt() and enable_irq() - * has to be called so that other devices on the line work. - */ - while (atomic_dec_return(&phydev->irq_disable) >= 0) - enable_irq(phydev->irq); - - return err; -} -EXPORT_SYMBOL(phy_stop_interrupts); - - -/** - * phy_change - Scheduled by the phy_interrupt/timer to handle PHY changes - * @work: work_struct that describes the work to be done - */ -static void phy_change(struct work_struct *work) -{ - int err; - struct phy_device *phydev = - container_of(work, struct phy_device, phy_queue); - - if (phydev->drv->did_interrupt && - !phydev->drv->did_interrupt(phydev)) - goto ignore; - - err = phy_disable_interrupts(phydev); - - if (err) - goto phy_err; - - mutex_lock(&phydev->lock); - if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) - phydev->state = PHY_CHANGELINK; - mutex_unlock(&phydev->lock); - - atomic_dec(&phydev->irq_disable); - enable_irq(phydev->irq); - - /* Reenable interrupts */ - if (PHY_HALTED != phydev->state) - err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); - - if (err) - goto irq_enable_err; - - /* reschedule state queue work to run as soon as possible */ - cancel_delayed_work_sync(&phydev->state_queue); - schedule_delayed_work(&phydev->state_queue, 0); - - return; - -ignore: - atomic_dec(&phydev->irq_disable); - enable_irq(phydev->irq); - return; - -irq_enable_err: - disable_irq(phydev->irq); - atomic_inc(&phydev->irq_disable); -phy_err: - phy_error(phydev); -} - -/** - * phy_stop - Bring down the PHY link, and stop checking the status - * @phydev: target phy_device struct - */ -void phy_stop(struct phy_device *phydev) -{ - mutex_lock(&phydev->lock); - - if (PHY_HALTED == phydev->state) - goto out_unlock; - - if (phydev->irq != PHY_POLL) { - /* Disable PHY Interrupts */ - phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); - - /* Clear any pending interrupts */ - phy_clear_interrupt(phydev); - } - - phydev->state = PHY_HALTED; - -out_unlock: - mutex_unlock(&phydev->lock); - - /* - * Cannot call flush_scheduled_work() here as desired because - * of rtnl_lock(), but PHY_HALTED shall guarantee phy_change() - * will not reenable interrupts. - */ -} - - -/** - * phy_start - start or restart a PHY device - * @phydev: target phy_device struct - * - * Description: Indicates the attached device's readiness to - * handle PHY-related work. Used during startup to start the - * PHY, and after a call to phy_stop() to resume operation. - * Also used to indicate the MDIO bus has cleared an error - * condition. - */ -void phy_start(struct phy_device *phydev) -{ - mutex_lock(&phydev->lock); - - switch (phydev->state) { - case PHY_STARTING: - phydev->state = PHY_PENDING; - break; - case PHY_READY: - phydev->state = PHY_UP; - break; - case PHY_HALTED: - phydev->state = PHY_RESUMING; - default: - break; - } - mutex_unlock(&phydev->lock); -} -EXPORT_SYMBOL(phy_stop); -EXPORT_SYMBOL(phy_start); - -/** - * phy_state_machine - Handle the state machine - * @work: work_struct that describes the work to be done - */ -void phy_state_machine(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct phy_device *phydev = - container_of(dwork, struct phy_device, state_queue); - int needs_aneg = 0; - int err = 0; - - mutex_lock(&phydev->lock); - - if (phydev->adjust_state) - phydev->adjust_state(phydev->attached_dev); - - switch(phydev->state) { - case PHY_DOWN: - case PHY_STARTING: - case PHY_READY: - case PHY_PENDING: - break; - case PHY_UP: - needs_aneg = 1; - - phydev->link_timeout = PHY_AN_TIMEOUT; - - break; - case PHY_AN: - err = phy_read_status(phydev); - - if (err < 0) - break; - - /* If the link is down, give up on - * negotiation for now */ - if (!phydev->link) { - phydev->state = PHY_NOLINK; - netif_carrier_off(phydev->attached_dev); - phydev->adjust_link(phydev->attached_dev); - break; - } - - /* Check if negotiation is done. Break - * if there's an error */ - err = phy_aneg_done(phydev); - if (err < 0) - break; - - /* If AN is done, we're running */ - if (err > 0) { - phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - phydev->adjust_link(phydev->attached_dev); - - } else if (0 == phydev->link_timeout--) { - int idx; - - needs_aneg = 1; - /* If we have the magic_aneg bit, - * we try again */ - if (phydev->drv->flags & PHY_HAS_MAGICANEG) - break; - - /* The timer expired, and we still - * don't have a setting, so we try - * forcing it until we find one that - * works, starting from the fastest speed, - * and working our way down */ - idx = phy_find_valid(0, phydev->supported); - - phydev->speed = settings[idx].speed; - phydev->duplex = settings[idx].duplex; - - phydev->autoneg = AUTONEG_DISABLE; - - pr_info("Trying %d/%s\n", phydev->speed, - DUPLEX_FULL == - phydev->duplex ? - "FULL" : "HALF"); - } - break; - case PHY_NOLINK: - err = phy_read_status(phydev); - - if (err) - break; - - if (phydev->link) { - phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - phydev->adjust_link(phydev->attached_dev); - } - break; - case PHY_FORCING: - err = genphy_update_link(phydev); - - if (err) - break; - - if (phydev->link) { - phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - } else { - if (0 == phydev->link_timeout--) { - phy_force_reduction(phydev); - needs_aneg = 1; - } - } - - phydev->adjust_link(phydev->attached_dev); - break; - case PHY_RUNNING: - /* Only register a CHANGE if we are - * polling */ - if (PHY_POLL == phydev->irq) - phydev->state = PHY_CHANGELINK; - break; - case PHY_CHANGELINK: - err = phy_read_status(phydev); - - if (err) - break; - - if (phydev->link) { - phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - } else { - phydev->state = PHY_NOLINK; - netif_carrier_off(phydev->attached_dev); - } - - phydev->adjust_link(phydev->attached_dev); - - if (PHY_POLL != phydev->irq) - err = phy_config_interrupt(phydev, - PHY_INTERRUPT_ENABLED); - break; - case PHY_HALTED: - if (phydev->link) { - phydev->link = 0; - netif_carrier_off(phydev->attached_dev); - phydev->adjust_link(phydev->attached_dev); - } - break; - case PHY_RESUMING: - - err = phy_clear_interrupt(phydev); - - if (err) - break; - - err = phy_config_interrupt(phydev, - PHY_INTERRUPT_ENABLED); - - if (err) - break; - - if (AUTONEG_ENABLE == phydev->autoneg) { - err = phy_aneg_done(phydev); - if (err < 0) - break; - - /* err > 0 if AN is done. - * Otherwise, it's 0, and we're - * still waiting for AN */ - if (err > 0) { - err = phy_read_status(phydev); - if (err) - break; - - if (phydev->link) { - phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - } else - phydev->state = PHY_NOLINK; - phydev->adjust_link(phydev->attached_dev); - } else { - phydev->state = PHY_AN; - phydev->link_timeout = PHY_AN_TIMEOUT; - } - } else { - err = phy_read_status(phydev); - if (err) - break; - - if (phydev->link) { - phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - } else - phydev->state = PHY_NOLINK; - phydev->adjust_link(phydev->attached_dev); - } - break; - } - - mutex_unlock(&phydev->lock); - - if (needs_aneg) - err = phy_start_aneg(phydev); - - if (err < 0) - phy_error(phydev); - - schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ); -} diff --git a/ANDROID_3.4.5/drivers/net/phy/phy_device.c b/ANDROID_3.4.5/drivers/net/phy/phy_device.c deleted file mode 100644 index e8c42d6a..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/phy_device.c +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * drivers/net/phy/phy_device.c - * - * Framework for finding and configuring PHYs. - * Also contains generic PHY driver - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -MODULE_DESCRIPTION("PHY library"); -MODULE_AUTHOR("Andy Fleming"); -MODULE_LICENSE("GPL"); - -void phy_device_free(struct phy_device *phydev) -{ - kfree(phydev); -} -EXPORT_SYMBOL(phy_device_free); - -static void phy_device_release(struct device *dev) -{ - phy_device_free(to_phy_device(dev)); -} - -static struct phy_driver genphy_driver; -extern int mdio_bus_init(void); -extern void mdio_bus_exit(void); - -static LIST_HEAD(phy_fixup_list); -static DEFINE_MUTEX(phy_fixup_lock); - -static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, - u32 flags, phy_interface_t interface); - -/* - * Creates a new phy_fixup and adds it to the list - * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID) - * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY) - * It can also be PHY_ANY_UID - * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before - * comparison - * @run: The actual code to be run when a matching PHY is found - */ -int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, - int (*run)(struct phy_device *)) -{ - struct phy_fixup *fixup; - - fixup = kzalloc(sizeof(struct phy_fixup), GFP_KERNEL); - if (!fixup) - return -ENOMEM; - - strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id)); - fixup->phy_uid = phy_uid; - fixup->phy_uid_mask = phy_uid_mask; - fixup->run = run; - - mutex_lock(&phy_fixup_lock); - list_add_tail(&fixup->list, &phy_fixup_list); - mutex_unlock(&phy_fixup_lock); - - return 0; -} -EXPORT_SYMBOL(phy_register_fixup); - -/* Registers a fixup to be run on any PHY with the UID in phy_uid */ -int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, - int (*run)(struct phy_device *)) -{ - return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run); -} -EXPORT_SYMBOL(phy_register_fixup_for_uid); - -/* Registers a fixup to be run on the PHY with id string bus_id */ -int phy_register_fixup_for_id(const char *bus_id, - int (*run)(struct phy_device *)) -{ - return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run); -} -EXPORT_SYMBOL(phy_register_fixup_for_id); - -/* - * Returns 1 if fixup matches phydev in bus_id and phy_uid. - * Fixups can be set to match any in one or more fields. - */ -static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) -{ - if (strcmp(fixup->bus_id, dev_name(&phydev->dev)) != 0) - if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0) - return 0; - - if ((fixup->phy_uid & fixup->phy_uid_mask) != - (phydev->phy_id & fixup->phy_uid_mask)) - if (fixup->phy_uid != PHY_ANY_UID) - return 0; - - return 1; -} - -/* Runs any matching fixups for this phydev */ -int phy_scan_fixups(struct phy_device *phydev) -{ - struct phy_fixup *fixup; - - mutex_lock(&phy_fixup_lock); - list_for_each_entry(fixup, &phy_fixup_list, list) { - if (phy_needs_fixup(phydev, fixup)) { - int err; - - err = fixup->run(phydev); - - if (err < 0) { - mutex_unlock(&phy_fixup_lock); - return err; - } - } - } - mutex_unlock(&phy_fixup_lock); - - return 0; -} -EXPORT_SYMBOL(phy_scan_fixups); - -static struct phy_device* phy_device_create(struct mii_bus *bus, - int addr, int phy_id) -{ - struct phy_device *dev; - - /* We allocate the device, and initialize the - * default values */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - - if (NULL == dev) - return (struct phy_device*) PTR_ERR((void*)-ENOMEM); - - dev->dev.release = phy_device_release; - - dev->speed = 0; - dev->duplex = -1; - dev->pause = dev->asym_pause = 0; - dev->link = 1; - dev->interface = PHY_INTERFACE_MODE_GMII; - - dev->autoneg = AUTONEG_ENABLE; - - dev->addr = addr; - dev->phy_id = phy_id; - dev->bus = bus; - dev->dev.parent = bus->parent; - dev->dev.bus = &mdio_bus_type; - dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL; - dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr); - - dev->state = PHY_DOWN; - - mutex_init(&dev->lock); - INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); - - /* Request the appropriate module unconditionally; don't - bother trying to do so only if it isn't already loaded, - because that gets complicated. A hotplug event would have - done an unconditional modprobe anyway. - We don't do normal hotplug because it won't work for MDIO - -- because it relies on the device staying around for long - enough for the driver to get loaded. With MDIO, the NIC - driver will get bored and give up as soon as it finds that - there's no driver _already_ loaded. */ - request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id)); - - return dev; -} - -/** - * get_phy_id - reads the specified addr for its ID. - * @bus: the target MII bus - * @addr: PHY address on the MII bus - * @phy_id: where to store the ID retrieved. - * - * Description: Reads the ID registers of the PHY at @addr on the - * @bus, stores it in @phy_id and returns zero on success. - */ -int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) -{ - int phy_reg; - - /* Grab the bits from PHYIR1, and put them - * in the upper half */ - phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); - - if (phy_reg < 0) - return -EIO; - - *phy_id = (phy_reg & 0xffff) << 16; - - /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); - - if (phy_reg < 0) - return -EIO; - - *phy_id |= (phy_reg & 0xffff); - - return 0; -} -EXPORT_SYMBOL(get_phy_id); - -/** - * get_phy_device - reads the specified PHY device and returns its @phy_device struct - * @bus: the target MII bus - * @addr: PHY address on the MII bus - * - * Description: Reads the ID registers of the PHY at @addr on the - * @bus, then allocates and returns the phy_device to represent it. - */ -struct phy_device * get_phy_device(struct mii_bus *bus, int addr) -{ - struct phy_device *dev = NULL; - u32 phy_id; - int r; - - r = get_phy_id(bus, addr, &phy_id); - if (r) - return ERR_PTR(r); - - /* If the phy_id is mostly Fs, there is no device there */ - if ((phy_id & 0x1fffffff) == 0x1fffffff) - return NULL; - - dev = phy_device_create(bus, addr, phy_id); - - return dev; -} -EXPORT_SYMBOL(get_phy_device); - -/** - * phy_device_register - Register the phy device on the MDIO bus - * @phydev: phy_device structure to be added to the MDIO bus - */ -int phy_device_register(struct phy_device *phydev) -{ - int err; - - /* Don't register a phy if one is already registered at this - * address */ - if (phydev->bus->phy_map[phydev->addr]) - return -EINVAL; - phydev->bus->phy_map[phydev->addr] = phydev; - - /* Run all of the fixups for this PHY */ - phy_scan_fixups(phydev); - - err = device_register(&phydev->dev); - if (err) { - pr_err("phy %d failed to register\n", phydev->addr); - goto out; - } - - return 0; - - out: - phydev->bus->phy_map[phydev->addr] = NULL; - return err; -} -EXPORT_SYMBOL(phy_device_register); - -/** - * phy_find_first - finds the first PHY device on the bus - * @bus: the target MII bus - */ -struct phy_device *phy_find_first(struct mii_bus *bus) -{ - int addr; - - for (addr = 0; addr < PHY_MAX_ADDR; addr++) { - if (bus->phy_map[addr]) - return bus->phy_map[addr]; - } - return NULL; -} -EXPORT_SYMBOL(phy_find_first); - -/** - * phy_prepare_link - prepares the PHY layer to monitor link status - * @phydev: target phy_device struct - * @handler: callback function for link status change notifications - * - * Description: Tells the PHY infrastructure to handle the - * gory details on monitoring link status (whether through - * polling or an interrupt), and to call back to the - * connected device driver when the link status changes. - * If you want to monitor your own link state, don't call - * this function. - */ -static void phy_prepare_link(struct phy_device *phydev, - void (*handler)(struct net_device *)) -{ - phydev->adjust_link = handler; -} - -/** - * phy_connect_direct - connect an ethernet device to a specific phy_device - * @dev: the network device to connect - * @phydev: the pointer to the phy device - * @handler: callback function for state change notifications - * @flags: PHY device's dev_flags - * @interface: PHY device's interface - */ -int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, - void (*handler)(struct net_device *), u32 flags, - phy_interface_t interface) -{ - int rc; - - rc = phy_attach_direct(dev, phydev, flags, interface); - if (rc) - return rc; - - phy_prepare_link(phydev, handler); - phy_start_machine(phydev, NULL); - if (phydev->irq > 0) - phy_start_interrupts(phydev); - - return 0; -} -EXPORT_SYMBOL(phy_connect_direct); - -/** - * phy_connect - connect an ethernet device to a PHY device - * @dev: the network device to connect - * @bus_id: the id string of the PHY device to connect - * @handler: callback function for state change notifications - * @flags: PHY device's dev_flags - * @interface: PHY device's interface - * - * Description: Convenience function for connecting ethernet - * devices to PHY devices. The default behavior is for - * the PHY infrastructure to handle everything, and only notify - * the connected driver when the link status changes. If you - * don't want, or can't use the provided functionality, you may - * choose to call only the subset of functions which provide - * the desired functionality. - */ -struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, - void (*handler)(struct net_device *), u32 flags, - phy_interface_t interface) -{ - struct phy_device *phydev; - struct device *d; - int rc; - - /* Search the list of PHY devices on the mdio bus for the - * PHY with the requested name */ - d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id); - if (!d) { - pr_err("PHY %s not found\n", bus_id); - return ERR_PTR(-ENODEV); - } - phydev = to_phy_device(d); - - rc = phy_connect_direct(dev, phydev, handler, flags, interface); - if (rc) - return ERR_PTR(rc); - - return phydev; -} -EXPORT_SYMBOL(phy_connect); - -/** - * phy_disconnect - disable interrupts, stop state machine, and detach a PHY device - * @phydev: target phy_device struct - */ -void phy_disconnect(struct phy_device *phydev) -{ - if (phydev->irq > 0) - phy_stop_interrupts(phydev); - - phy_stop_machine(phydev); - - phydev->adjust_link = NULL; - - phy_detach(phydev); -} -EXPORT_SYMBOL(phy_disconnect); - -int phy_init_hw(struct phy_device *phydev) -{ - int ret; - - if (!phydev->drv || !phydev->drv->config_init) - return 0; - - ret = phy_scan_fixups(phydev); - if (ret < 0) - return ret; - - return phydev->drv->config_init(phydev); -} - -/** - * phy_attach_direct - attach a network device to a given PHY device pointer - * @dev: network device to attach - * @phydev: Pointer to phy_device to attach - * @flags: PHY device's dev_flags - * @interface: PHY device's interface - * - * Description: Called by drivers to attach to a particular PHY - * device. The phy_device is found, and properly hooked up - * to the phy_driver. If no driver is attached, then the - * genphy_driver is used. The phy_device is given a ptr to - * the attaching device, and given a callback for link status - * change. The phy_device is returned to the attaching driver. - */ -static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, - u32 flags, phy_interface_t interface) -{ - struct device *d = &phydev->dev; - int err; - - /* Assume that if there is no driver, that it doesn't - * exist, and we should use the genphy driver. */ - if (NULL == d->driver) { - d->driver = &genphy_driver.driver; - - err = d->driver->probe(d); - if (err >= 0) - err = device_bind_driver(d); - - if (err) - return err; - } - - if (phydev->attached_dev) { - dev_err(&dev->dev, "PHY already attached\n"); - return -EBUSY; - } - - phydev->attached_dev = dev; - dev->phydev = phydev; - - phydev->dev_flags = flags; - - phydev->interface = interface; - - phydev->state = PHY_READY; - - /* Do initial configuration here, now that - * we have certain key parameters - * (dev_flags and interface) */ - err = phy_init_hw(phydev); - if (err) - phy_detach(phydev); - - return err; -} - -/** - * phy_attach - attach a network device to a particular PHY device - * @dev: network device to attach - * @bus_id: Bus ID of PHY device to attach - * @flags: PHY device's dev_flags - * @interface: PHY device's interface - * - * Description: Same as phy_attach_direct() except that a PHY bus_id - * string is passed instead of a pointer to a struct phy_device. - */ -struct phy_device *phy_attach(struct net_device *dev, - const char *bus_id, u32 flags, phy_interface_t interface) -{ - struct bus_type *bus = &mdio_bus_type; - struct phy_device *phydev; - struct device *d; - int rc; - - /* Search the list of PHY devices on the mdio bus for the - * PHY with the requested name */ - d = bus_find_device_by_name(bus, NULL, bus_id); - if (!d) { - pr_err("PHY %s not found\n", bus_id); - return ERR_PTR(-ENODEV); - } - phydev = to_phy_device(d); - - rc = phy_attach_direct(dev, phydev, flags, interface); - if (rc) - return ERR_PTR(rc); - - return phydev; -} -EXPORT_SYMBOL(phy_attach); - -/** - * phy_detach - detach a PHY device from its network device - * @phydev: target phy_device struct - */ -void phy_detach(struct phy_device *phydev) -{ - phydev->attached_dev->phydev = NULL; - phydev->attached_dev = NULL; - - /* If the device had no specific driver before (i.e. - it - * was using the generic driver), we unbind the device - * from the generic driver so that there's a chance a - * real driver could be loaded */ - if (phydev->dev.driver == &genphy_driver.driver) - device_release_driver(&phydev->dev); -} -EXPORT_SYMBOL(phy_detach); - - -/* Generic PHY support and helper functions */ - -/** - * genphy_config_advert - sanitize and advertise auto-negotiation parameters - * @phydev: target phy_device struct - * - * Description: Writes MII_ADVERTISE with the appropriate values, - * after sanitizing the values to make sure we only advertise - * what is supported. Returns < 0 on error, 0 if the PHY's advertisement - * hasn't changed, and > 0 if it has changed. - */ -static int genphy_config_advert(struct phy_device *phydev) -{ - u32 advertise; - int oldadv, adv; - int err, changed = 0; - - /* Only allow advertising what - * this PHY supports */ - phydev->advertising &= phydev->supported; - advertise = phydev->advertising; - - /* Setup standard advertisement */ - oldadv = adv = phy_read(phydev, MII_ADVERTISE); - - if (adv < 0) - return adv; - - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | - ADVERTISE_PAUSE_ASYM); - adv |= ethtool_adv_to_mii_adv_t(advertise); - - if (adv != oldadv) { - err = phy_write(phydev, MII_ADVERTISE, adv); - - if (err < 0) - return err; - changed = 1; - } - - /* Configure gigabit if it's supported */ - if (phydev->supported & (SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full)) { - oldadv = adv = phy_read(phydev, MII_CTRL1000); - - if (adv < 0) - return adv; - - adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); - adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); - - if (adv != oldadv) { - err = phy_write(phydev, MII_CTRL1000, adv); - - if (err < 0) - return err; - changed = 1; - } - } - - return changed; -} - -/** - * genphy_setup_forced - configures/forces speed/duplex from @phydev - * @phydev: target phy_device struct - * - * Description: Configures MII_BMCR to force speed/duplex - * to the values in phydev. Assumes that the values are valid. - * Please see phy_sanitize_settings(). - */ -static int genphy_setup_forced(struct phy_device *phydev) -{ - int err; - int ctl = 0; - - phydev->pause = phydev->asym_pause = 0; - - if (SPEED_1000 == phydev->speed) - ctl |= BMCR_SPEED1000; - else if (SPEED_100 == phydev->speed) - ctl |= BMCR_SPEED100; - - if (DUPLEX_FULL == phydev->duplex) - ctl |= BMCR_FULLDPLX; - - err = phy_write(phydev, MII_BMCR, ctl); - - return err; -} - - -/** - * genphy_restart_aneg - Enable and Restart Autonegotiation - * @phydev: target phy_device struct - */ -int genphy_restart_aneg(struct phy_device *phydev) -{ - int ctl; - - ctl = phy_read(phydev, MII_BMCR); - - if (ctl < 0) - return ctl; - - ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); - - /* Don't isolate the PHY if we're negotiating */ - ctl &= ~(BMCR_ISOLATE); - - ctl = phy_write(phydev, MII_BMCR, ctl); - - return ctl; -} -EXPORT_SYMBOL(genphy_restart_aneg); - - -/** - * genphy_config_aneg - restart auto-negotiation or write BMCR - * @phydev: target phy_device struct - * - * Description: If auto-negotiation is enabled, we configure the - * advertising, and then restart auto-negotiation. If it is not - * enabled, then we write the BMCR. - */ -int genphy_config_aneg(struct phy_device *phydev) -{ - int result; - - if (AUTONEG_ENABLE != phydev->autoneg) - return genphy_setup_forced(phydev); - - result = genphy_config_advert(phydev); - - if (result < 0) /* error */ - return result; - - if (result == 0) { - /* Advertisement hasn't changed, but maybe aneg was never on to - * begin with? Or maybe phy was isolated? */ - int ctl = phy_read(phydev, MII_BMCR); - - if (ctl < 0) - return ctl; - - if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) - result = 1; /* do restart aneg */ - } - - /* Only restart aneg if we are advertising something different - * than we were before. */ - if (result > 0) - result = genphy_restart_aneg(phydev); - - return result; -} -EXPORT_SYMBOL(genphy_config_aneg); - -/** - * genphy_update_link - update link status in @phydev - * @phydev: target phy_device struct - * - * Description: Update the value in phydev->link to reflect the - * current link value. In order to do this, we need to read - * the status register twice, keeping the second value. - */ -int genphy_update_link(struct phy_device *phydev) -{ - int status; - - /* Do a fake read */ - status = phy_read(phydev, MII_BMSR); - - if (status < 0) - return status; - - /* Read link and autonegotiation status */ - status = phy_read(phydev, MII_BMSR); - - if (status < 0) - return status; - - if ((status & BMSR_LSTATUS) == 0) - phydev->link = 0; - else - phydev->link = 1; - - return 0; -} -EXPORT_SYMBOL(genphy_update_link); - -/** - * genphy_read_status - check the link status and update current link state - * @phydev: target phy_device struct - * - * Description: Check the link, then figure out the current state - * by comparing what we advertise with what the link partner - * advertises. Start by checking the gigabit possibilities, - * then move on to 10/100. - */ -int genphy_read_status(struct phy_device *phydev) -{ - int adv; - int err; - int lpa; - int lpagb = 0; - - /* Update the link, but return if there - * was an error */ - err = genphy_update_link(phydev); - if (err) - return err; - - if (AUTONEG_ENABLE == phydev->autoneg) { - if (phydev->supported & (SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full)) { - lpagb = phy_read(phydev, MII_STAT1000); - - if (lpagb < 0) - return lpagb; - - adv = phy_read(phydev, MII_CTRL1000); - - if (adv < 0) - return adv; - - lpagb &= adv << 2; - } - - lpa = phy_read(phydev, MII_LPA); - - if (lpa < 0) - return lpa; - - adv = phy_read(phydev, MII_ADVERTISE); - - if (adv < 0) - return adv; - - lpa &= adv; - - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_HALF; - phydev->pause = phydev->asym_pause = 0; - - if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { - phydev->speed = SPEED_1000; - - if (lpagb & LPA_1000FULL) - phydev->duplex = DUPLEX_FULL; - } else if (lpa & (LPA_100FULL | LPA_100HALF)) { - phydev->speed = SPEED_100; - - if (lpa & LPA_100FULL) - phydev->duplex = DUPLEX_FULL; - } else - if (lpa & LPA_10FULL) - phydev->duplex = DUPLEX_FULL; - - if (phydev->duplex == DUPLEX_FULL){ - phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; - phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; - } - } else { - int bmcr = phy_read(phydev, MII_BMCR); - if (bmcr < 0) - return bmcr; - - if (bmcr & BMCR_FULLDPLX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - if (bmcr & BMCR_SPEED1000) - phydev->speed = SPEED_1000; - else if (bmcr & BMCR_SPEED100) - phydev->speed = SPEED_100; - else - phydev->speed = SPEED_10; - - phydev->pause = phydev->asym_pause = 0; - } - - return 0; -} -EXPORT_SYMBOL(genphy_read_status); - -static int genphy_config_init(struct phy_device *phydev) -{ - int val; - u32 features; - - /* For now, I'll claim that the generic driver supports - * all possible port types */ - features = (SUPPORTED_TP | SUPPORTED_MII - | SUPPORTED_AUI | SUPPORTED_FIBRE | - SUPPORTED_BNC); - - /* Do we support autonegotiation? */ - val = phy_read(phydev, MII_BMSR); - - if (val < 0) - return val; - - if (val & BMSR_ANEGCAPABLE) - features |= SUPPORTED_Autoneg; - - if (val & BMSR_100FULL) - features |= SUPPORTED_100baseT_Full; - if (val & BMSR_100HALF) - features |= SUPPORTED_100baseT_Half; - if (val & BMSR_10FULL) - features |= SUPPORTED_10baseT_Full; - if (val & BMSR_10HALF) - features |= SUPPORTED_10baseT_Half; - - if (val & BMSR_ESTATEN) { - val = phy_read(phydev, MII_ESTATUS); - - if (val < 0) - return val; - - if (val & ESTATUS_1000_TFULL) - features |= SUPPORTED_1000baseT_Full; - if (val & ESTATUS_1000_THALF) - features |= SUPPORTED_1000baseT_Half; - } - - phydev->supported = features; - phydev->advertising = features; - - return 0; -} -int genphy_suspend(struct phy_device *phydev) -{ - int value; - - mutex_lock(&phydev->lock); - - value = phy_read(phydev, MII_BMCR); - phy_write(phydev, MII_BMCR, (value | BMCR_PDOWN)); - - mutex_unlock(&phydev->lock); - - return 0; -} -EXPORT_SYMBOL(genphy_suspend); - -int genphy_resume(struct phy_device *phydev) -{ - int value; - - mutex_lock(&phydev->lock); - - value = phy_read(phydev, MII_BMCR); - phy_write(phydev, MII_BMCR, (value & ~BMCR_PDOWN)); - - mutex_unlock(&phydev->lock); - - return 0; -} -EXPORT_SYMBOL(genphy_resume); - -/** - * phy_probe - probe and init a PHY device - * @dev: device to probe and init - * - * Description: Take care of setting up the phy_device structure, - * set the state to READY (the driver's init function should - * set it to STARTING if needed). - */ -static int phy_probe(struct device *dev) -{ - struct phy_device *phydev; - struct phy_driver *phydrv; - struct device_driver *drv; - int err = 0; - - phydev = to_phy_device(dev); - - drv = phydev->dev.driver; - phydrv = to_phy_driver(drv); - phydev->drv = phydrv; - - /* Disable the interrupt if the PHY doesn't support it */ - if (!(phydrv->flags & PHY_HAS_INTERRUPT)) - phydev->irq = PHY_POLL; - - mutex_lock(&phydev->lock); - - /* Start out supporting everything. Eventually, - * a controller will attach, and may modify one - * or both of these values */ - phydev->supported = phydrv->features; - phydev->advertising = phydrv->features; - - /* Set the state to READY by default */ - phydev->state = PHY_READY; - - if (phydev->drv->probe) - err = phydev->drv->probe(phydev); - - mutex_unlock(&phydev->lock); - - return err; - -} - -static int phy_remove(struct device *dev) -{ - struct phy_device *phydev; - - phydev = to_phy_device(dev); - - mutex_lock(&phydev->lock); - phydev->state = PHY_DOWN; - mutex_unlock(&phydev->lock); - - if (phydev->drv->remove) - phydev->drv->remove(phydev); - phydev->drv = NULL; - - return 0; -} - -/** - * phy_driver_register - register a phy_driver with the PHY layer - * @new_driver: new phy_driver to register - */ -int phy_driver_register(struct phy_driver *new_driver) -{ - int retval; - - new_driver->driver.name = new_driver->name; - new_driver->driver.bus = &mdio_bus_type; - new_driver->driver.probe = phy_probe; - new_driver->driver.remove = phy_remove; - - retval = driver_register(&new_driver->driver); - - if (retval) { - printk(KERN_ERR "%s: Error %d in registering driver\n", - new_driver->name, retval); - - return retval; - } - - pr_debug("%s: Registered new driver\n", new_driver->name); - - return 0; -} -EXPORT_SYMBOL(phy_driver_register); - -void phy_driver_unregister(struct phy_driver *drv) -{ - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL(phy_driver_unregister); - -static struct phy_driver genphy_driver = { - .phy_id = 0xffffffff, - .phy_id_mask = 0xffffffff, - .name = "Generic PHY", - .config_init = genphy_config_init, - .features = 0, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .suspend = genphy_suspend, - .resume = genphy_resume, - .driver = {.owner= THIS_MODULE, }, -}; - -static int __init phy_init(void) -{ - int rc; - - rc = mdio_bus_init(); - if (rc) - return rc; - - rc = phy_driver_register(&genphy_driver); - if (rc) - mdio_bus_exit(); - - return rc; -} - -static void __exit phy_exit(void) -{ - phy_driver_unregister(&genphy_driver); - mdio_bus_exit(); -} - -subsys_initcall(phy_init); -module_exit(phy_exit); diff --git a/ANDROID_3.4.5/drivers/net/phy/qsemi.c b/ANDROID_3.4.5/drivers/net/phy/qsemi.c deleted file mode 100644 index fe0d0a15..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/qsemi.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * drivers/net/phy/qsemi.c - * - * Driver for Quality Semiconductor PHYs - * - * Author: Andy Fleming - * - * Copyright (c) 2004 Freescale Semiconductor, 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/kernel.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/unistd.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> - -/* ------------------------------------------------------------------------- */ -/* The Quality Semiconductor QS6612 is used on the RPX CLLF */ - -/* register definitions */ - -#define MII_QS6612_MCR 17 /* Mode Control Register */ -#define MII_QS6612_FTR 27 /* Factory Test Register */ -#define MII_QS6612_MCO 28 /* Misc. Control Register */ -#define MII_QS6612_ISR 29 /* Interrupt Source Register */ -#define MII_QS6612_IMR 30 /* Interrupt Mask Register */ -#define MII_QS6612_IMR_INIT 0x003a -#define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */ - -#define QS6612_PCR_AN_COMPLETE 0x1000 -#define QS6612_PCR_RLBEN 0x0200 -#define QS6612_PCR_DCREN 0x0100 -#define QS6612_PCR_4B5BEN 0x0040 -#define QS6612_PCR_TX_ISOLATE 0x0020 -#define QS6612_PCR_MLT3_DIS 0x0002 -#define QS6612_PCR_SCRM_DESCRM 0x0001 - -MODULE_DESCRIPTION("Quality Semiconductor PHY driver"); -MODULE_AUTHOR("Andy Fleming"); -MODULE_LICENSE("GPL"); - -/* Returns 0, unless there's a write error */ -static int qs6612_config_init(struct phy_device *phydev) -{ - /* The PHY powers up isolated on the RPX, - * so send a command to allow operation. - * XXX - My docs indicate this should be 0x0940 - * ...or something. The current value sets three - * reserved bits, bit 11, which specifies it should be - * set to one, bit 10, which specifies it should be set - * to 0, and bit 7, which doesn't specify. However, my - * docs are preliminary, and I will leave it like this - * until someone more knowledgable corrects me or it. - * -- Andy Fleming - */ - return phy_write(phydev, MII_QS6612_PCR, 0x0dc0); -} - -static int qs6612_ack_interrupt(struct phy_device *phydev) -{ - int err; - - err = phy_read(phydev, MII_QS6612_ISR); - - if (err < 0) - return err; - - err = phy_read(phydev, MII_BMSR); - - if (err < 0) - return err; - - err = phy_read(phydev, MII_EXPANSION); - - if (err < 0) - return err; - - return 0; -} - -static int qs6612_config_intr(struct phy_device *phydev) -{ - int err; - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_QS6612_IMR, - MII_QS6612_IMR_INIT); - else - err = phy_write(phydev, MII_QS6612_IMR, 0); - - return err; - -} - -static struct phy_driver qs6612_driver = { - .phy_id = 0x00181440, - .name = "QS6612", - .phy_id_mask = 0xfffffff0, - .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = qs6612_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = qs6612_ack_interrupt, - .config_intr = qs6612_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init qs6612_init(void) -{ - return phy_driver_register(&qs6612_driver); -} - -static void __exit qs6612_exit(void) -{ - phy_driver_unregister(&qs6612_driver); -} - -module_init(qs6612_init); -module_exit(qs6612_exit); - -static struct mdio_device_id __maybe_unused qs6612_tbl[] = { - { 0x00181440, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, qs6612_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/realtek.c b/ANDROID_3.4.5/drivers/net/phy/realtek.c deleted file mode 100644 index f414ffb5..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/realtek.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * drivers/net/phy/realtek.c - * - * Driver for Realtek PHYs - * - * Author: Johnson Leung <r58129@freescale.com> - * - * Copyright (c) 2004 Freescale Semiconductor, 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/phy.h> -#include <linux/module.h> - -#define RTL821x_PHYSR 0x11 -#define RTL821x_PHYSR_DUPLEX 0x2000 -#define RTL821x_PHYSR_SPEED 0xc000 -#define RTL821x_INER 0x12 -#define RTL821x_INER_INIT 0x6400 -#define RTL821x_INSR 0x13 - -MODULE_DESCRIPTION("Realtek PHY driver"); -MODULE_AUTHOR("Johnson Leung"); -MODULE_LICENSE("GPL"); - -static int rtl821x_ack_interrupt(struct phy_device *phydev) -{ - int err; - - err = phy_read(phydev, RTL821x_INSR); - - return (err < 0) ? err : 0; -} - -static int rtl821x_config_intr(struct phy_device *phydev) -{ - int err; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, RTL821x_INER, - RTL821x_INER_INIT); - else - err = phy_write(phydev, RTL821x_INER, 0); - - return err; -} - -/* RTL8211B */ -static struct phy_driver rtl821x_driver = { - .phy_id = 0x001cc912, - .name = "RTL821x Gigabit Ethernet", - .phy_id_mask = 0x001fffff, - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &rtl821x_ack_interrupt, - .config_intr = &rtl821x_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init realtek_init(void) -{ - int ret; - - ret = phy_driver_register(&rtl821x_driver); - - return ret; -} - -static void __exit realtek_exit(void) -{ - phy_driver_unregister(&rtl821x_driver); -} - -module_init(realtek_init); -module_exit(realtek_exit); - -static struct mdio_device_id __maybe_unused realtek_tbl[] = { - { 0x001cc912, 0x001fffff }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, realtek_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/smsc.c b/ANDROID_3.4.5/drivers/net/phy/smsc.c deleted file mode 100644 index fc3e7e96..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/smsc.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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@smsc.com - * - */ - -#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> - -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; -} - -static int smsc_phy_ack_interrupt(struct phy_device *phydev) -{ - int rc = phy_read (phydev, MII_LAN83C185_ISF); - - return rc < 0 ? rc : 0; -} - -static int smsc_phy_config_init(struct phy_device *phydev) -{ - int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); - if (rc < 0) - return rc; - - /* 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); -} - -static int lan911x_config_init(struct phy_device *phydev) -{ - return smsc_phy_ack_interrupt(phydev); -} - -static struct phy_driver lan83c185_driver = { - .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */ - .phy_id_mask = 0xfffffff0, - .name = "SMSC LAN83C185", - - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, - - /* basic functions */ - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .config_init = smsc_phy_config_init, - - /* IRQ related */ - .ack_interrupt = smsc_phy_ack_interrupt, - .config_intr = smsc_phy_config_intr, - - .suspend = genphy_suspend, - .resume = genphy_resume, - - .driver = { .owner = THIS_MODULE, } -}; - -static struct phy_driver lan8187_driver = { - .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */ - .phy_id_mask = 0xfffffff0, - .name = "SMSC LAN8187", - - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, - - /* basic functions */ - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .config_init = smsc_phy_config_init, - - /* IRQ related */ - .ack_interrupt = smsc_phy_ack_interrupt, - .config_intr = smsc_phy_config_intr, - - .suspend = genphy_suspend, - .resume = genphy_resume, - - .driver = { .owner = THIS_MODULE, } -}; - -static struct phy_driver lan8700_driver = { - .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */ - .phy_id_mask = 0xfffffff0, - .name = "SMSC LAN8700", - - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, - - /* basic functions */ - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .config_init = smsc_phy_config_init, - - /* IRQ related */ - .ack_interrupt = smsc_phy_ack_interrupt, - .config_intr = smsc_phy_config_intr, - - .suspend = genphy_suspend, - .resume = genphy_resume, - - .driver = { .owner = THIS_MODULE, } -}; - -static struct phy_driver lan911x_int_driver = { - .phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */ - .phy_id_mask = 0xfffffff0, - .name = "SMSC LAN911x Internal PHY", - - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, - - /* 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, - - .driver = { .owner = THIS_MODULE, } -}; - -static struct phy_driver lan8710_driver = { - .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */ - .phy_id_mask = 0xfffffff0, - .name = "SMSC LAN8710/LAN8720", - - .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, - - /* basic functions */ - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .config_init = smsc_phy_config_init, - - /* IRQ related */ - .ack_interrupt = smsc_phy_ack_interrupt, - .config_intr = smsc_phy_config_intr, - - .suspend = genphy_suspend, - .resume = genphy_resume, - - .driver = { .owner = THIS_MODULE, } -}; - -static int __init smsc_init(void) -{ - int ret; - - ret = phy_driver_register (&lan83c185_driver); - if (ret) - goto err1; - - ret = phy_driver_register (&lan8187_driver); - if (ret) - goto err2; - - ret = phy_driver_register (&lan8700_driver); - if (ret) - goto err3; - - ret = phy_driver_register (&lan911x_int_driver); - if (ret) - goto err4; - - ret = phy_driver_register (&lan8710_driver); - if (ret) - goto err5; - - return 0; - -err5: - phy_driver_unregister (&lan911x_int_driver); -err4: - phy_driver_unregister (&lan8700_driver); -err3: - phy_driver_unregister (&lan8187_driver); -err2: - phy_driver_unregister (&lan83c185_driver); -err1: - return ret; -} - -static void __exit smsc_exit(void) -{ - phy_driver_unregister (&lan8710_driver); - phy_driver_unregister (&lan911x_int_driver); - phy_driver_unregister (&lan8700_driver); - phy_driver_unregister (&lan8187_driver); - phy_driver_unregister (&lan83c185_driver); -} - -MODULE_DESCRIPTION("SMSC PHY driver"); -MODULE_AUTHOR("Herbert Valerio Riedel"); -MODULE_LICENSE("GPL"); - -module_init(smsc_init); -module_exit(smsc_exit); - -static struct mdio_device_id __maybe_unused smsc_tbl[] = { - { 0x0007c0a0, 0xfffffff0 }, - { 0x0007c0b0, 0xfffffff0 }, - { 0x0007c0c0, 0xfffffff0 }, - { 0x0007c0d0, 0xfffffff0 }, - { 0x0007c0f0, 0xfffffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, smsc_tbl); diff --git a/ANDROID_3.4.5/drivers/net/phy/spi_ks8995.c b/ANDROID_3.4.5/drivers/net/phy/spi_ks8995.c deleted file mode 100644 index 116a2dd7..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/spi_ks8995.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * SPI driver for Micrel/Kendin KS8995M ethernet switch - * - * Copyright (C) 2008 Gabor Juhos <juhosg at openwrt.org> - * - * This file was based on: drivers/spi/at25.c - * Copyright (C) 2006 David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/device.h> - -#include <linux/spi/spi.h> - -#define DRV_VERSION "0.1.1" -#define DRV_DESC "Micrel KS8995 Ethernet switch SPI driver" - -/* ------------------------------------------------------------------------ */ - -#define KS8995_REG_ID0 0x00 /* Chip ID0 */ -#define KS8995_REG_ID1 0x01 /* Chip ID1 */ - -#define KS8995_REG_GC0 0x02 /* Global Control 0 */ -#define KS8995_REG_GC1 0x03 /* Global Control 1 */ -#define KS8995_REG_GC2 0x04 /* Global Control 2 */ -#define KS8995_REG_GC3 0x05 /* Global Control 3 */ -#define KS8995_REG_GC4 0x06 /* Global Control 4 */ -#define KS8995_REG_GC5 0x07 /* Global Control 5 */ -#define KS8995_REG_GC6 0x08 /* Global Control 6 */ -#define KS8995_REG_GC7 0x09 /* Global Control 7 */ -#define KS8995_REG_GC8 0x0a /* Global Control 8 */ -#define KS8995_REG_GC9 0x0b /* Global Control 9 */ - -#define KS8995_REG_PC(p, r) ((0x10 * p) + r) /* Port Control */ -#define KS8995_REG_PS(p, r) ((0x10 * p) + r + 0xe) /* Port Status */ - -#define KS8995_REG_TPC0 0x60 /* TOS Priority Control 0 */ -#define KS8995_REG_TPC1 0x61 /* TOS Priority Control 1 */ -#define KS8995_REG_TPC2 0x62 /* TOS Priority Control 2 */ -#define KS8995_REG_TPC3 0x63 /* TOS Priority Control 3 */ -#define KS8995_REG_TPC4 0x64 /* TOS Priority Control 4 */ -#define KS8995_REG_TPC5 0x65 /* TOS Priority Control 5 */ -#define KS8995_REG_TPC6 0x66 /* TOS Priority Control 6 */ -#define KS8995_REG_TPC7 0x67 /* TOS Priority Control 7 */ - -#define KS8995_REG_MAC0 0x68 /* MAC address 0 */ -#define KS8995_REG_MAC1 0x69 /* MAC address 1 */ -#define KS8995_REG_MAC2 0x6a /* MAC address 2 */ -#define KS8995_REG_MAC3 0x6b /* MAC address 3 */ -#define KS8995_REG_MAC4 0x6c /* MAC address 4 */ -#define KS8995_REG_MAC5 0x6d /* MAC address 5 */ - -#define KS8995_REG_IAC0 0x6e /* Indirect Access Control 0 */ -#define KS8995_REG_IAC1 0x6f /* Indirect Access Control 0 */ -#define KS8995_REG_IAD7 0x70 /* Indirect Access Data 7 */ -#define KS8995_REG_IAD6 0x71 /* Indirect Access Data 6 */ -#define KS8995_REG_IAD5 0x72 /* Indirect Access Data 5 */ -#define KS8995_REG_IAD4 0x73 /* Indirect Access Data 4 */ -#define KS8995_REG_IAD3 0x74 /* Indirect Access Data 3 */ -#define KS8995_REG_IAD2 0x75 /* Indirect Access Data 2 */ -#define KS8995_REG_IAD1 0x76 /* Indirect Access Data 1 */ -#define KS8995_REG_IAD0 0x77 /* Indirect Access Data 0 */ - -#define KS8995_REGS_SIZE 0x80 - -#define ID1_CHIPID_M 0xf -#define ID1_CHIPID_S 4 -#define ID1_REVISION_M 0x7 -#define ID1_REVISION_S 1 -#define ID1_START_SW 1 /* start the switch */ - -#define FAMILY_KS8995 0x95 -#define CHIPID_M 0 - -#define KS8995_CMD_WRITE 0x02U -#define KS8995_CMD_READ 0x03U - -#define KS8995_RESET_DELAY 10 /* usec */ - -struct ks8995_pdata { - /* not yet implemented */ -}; - -struct ks8995_switch { - struct spi_device *spi; - struct mutex lock; - struct ks8995_pdata *pdata; -}; - -static inline u8 get_chip_id(u8 val) -{ - return (val >> ID1_CHIPID_S) & ID1_CHIPID_M; -} - -static inline u8 get_chip_rev(u8 val) -{ - return (val >> ID1_REVISION_S) & ID1_REVISION_M; -} - -/* ------------------------------------------------------------------------ */ -static int ks8995_read(struct ks8995_switch *ks, char *buf, - unsigned offset, size_t count) -{ - u8 cmd[2]; - struct spi_transfer t[2]; - struct spi_message m; - int err; - - spi_message_init(&m); - - memset(&t, 0, sizeof(t)); - - t[0].tx_buf = cmd; - t[0].len = sizeof(cmd); - spi_message_add_tail(&t[0], &m); - - t[1].rx_buf = buf; - t[1].len = count; - spi_message_add_tail(&t[1], &m); - - cmd[0] = KS8995_CMD_READ; - cmd[1] = offset; - - mutex_lock(&ks->lock); - err = spi_sync(ks->spi, &m); - mutex_unlock(&ks->lock); - - return err ? err : count; -} - - -static int ks8995_write(struct ks8995_switch *ks, char *buf, - unsigned offset, size_t count) -{ - u8 cmd[2]; - struct spi_transfer t[2]; - struct spi_message m; - int err; - - spi_message_init(&m); - - memset(&t, 0, sizeof(t)); - - t[0].tx_buf = cmd; - t[0].len = sizeof(cmd); - spi_message_add_tail(&t[0], &m); - - t[1].tx_buf = buf; - t[1].len = count; - spi_message_add_tail(&t[1], &m); - - cmd[0] = KS8995_CMD_WRITE; - cmd[1] = offset; - - mutex_lock(&ks->lock); - err = spi_sync(ks->spi, &m); - mutex_unlock(&ks->lock); - - return err ? err : count; -} - -static inline int ks8995_read_reg(struct ks8995_switch *ks, u8 addr, u8 *buf) -{ - return (ks8995_read(ks, buf, addr, 1) != 1); -} - -static inline int ks8995_write_reg(struct ks8995_switch *ks, u8 addr, u8 val) -{ - char buf = val; - - return (ks8995_write(ks, &buf, addr, 1) != 1); -} - -/* ------------------------------------------------------------------------ */ - -static int ks8995_stop(struct ks8995_switch *ks) -{ - return ks8995_write_reg(ks, KS8995_REG_ID1, 0); -} - -static int ks8995_start(struct ks8995_switch *ks) -{ - return ks8995_write_reg(ks, KS8995_REG_ID1, 1); -} - -static int ks8995_reset(struct ks8995_switch *ks) -{ - int err; - - err = ks8995_stop(ks); - if (err) - return err; - - udelay(KS8995_RESET_DELAY); - - return ks8995_start(ks); -} - -/* ------------------------------------------------------------------------ */ - -static ssize_t ks8995_registers_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) -{ - struct device *dev; - struct ks8995_switch *ks8995; - - dev = container_of(kobj, struct device, kobj); - ks8995 = dev_get_drvdata(dev); - - if (unlikely(off > KS8995_REGS_SIZE)) - return 0; - - if ((off + count) > KS8995_REGS_SIZE) - count = KS8995_REGS_SIZE - off; - - if (unlikely(!count)) - return count; - - return ks8995_read(ks8995, buf, off, count); -} - - -static ssize_t ks8995_registers_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) -{ - struct device *dev; - struct ks8995_switch *ks8995; - - dev = container_of(kobj, struct device, kobj); - ks8995 = dev_get_drvdata(dev); - - if (unlikely(off >= KS8995_REGS_SIZE)) - return -EFBIG; - - if ((off + count) > KS8995_REGS_SIZE) - count = KS8995_REGS_SIZE - off; - - if (unlikely(!count)) - return count; - - return ks8995_write(ks8995, buf, off, count); -} - - -static struct bin_attribute ks8995_registers_attr = { - .attr = { - .name = "registers", - .mode = S_IRUSR | S_IWUSR, - }, - .size = KS8995_REGS_SIZE, - .read = ks8995_registers_read, - .write = ks8995_registers_write, -}; - -/* ------------------------------------------------------------------------ */ - -static int __devinit ks8995_probe(struct spi_device *spi) -{ - struct ks8995_switch *ks; - struct ks8995_pdata *pdata; - u8 ids[2]; - int err; - - /* Chip description */ - pdata = spi->dev.platform_data; - - ks = kzalloc(sizeof(*ks), GFP_KERNEL); - if (!ks) { - dev_err(&spi->dev, "no memory for private data\n"); - return -ENOMEM; - } - - mutex_init(&ks->lock); - ks->pdata = pdata; - ks->spi = spi_dev_get(spi); - dev_set_drvdata(&spi->dev, ks); - - spi->mode = SPI_MODE_0; - spi->bits_per_word = 8; - err = spi_setup(spi); - if (err) { - dev_err(&spi->dev, "spi_setup failed, err=%d\n", err); - goto err_drvdata; - } - - err = ks8995_read(ks, ids, KS8995_REG_ID0, sizeof(ids)); - if (err < 0) { - dev_err(&spi->dev, "unable to read id registers, err=%d\n", - err); - goto err_drvdata; - } - - switch (ids[0]) { - case FAMILY_KS8995: - break; - default: - dev_err(&spi->dev, "unknown family id:%02x\n", ids[0]); - err = -ENODEV; - goto err_drvdata; - } - - err = ks8995_reset(ks); - if (err) - goto err_drvdata; - - err = sysfs_create_bin_file(&spi->dev.kobj, &ks8995_registers_attr); - if (err) { - dev_err(&spi->dev, "unable to create sysfs file, err=%d\n", - err); - goto err_drvdata; - } - - dev_info(&spi->dev, "KS89%02X device found, Chip ID:%01x, " - "Revision:%01x\n", ids[0], - get_chip_id(ids[1]), get_chip_rev(ids[1])); - - return 0; - -err_drvdata: - dev_set_drvdata(&spi->dev, NULL); - kfree(ks); - return err; -} - -static int __devexit ks8995_remove(struct spi_device *spi) -{ - struct ks8995_data *ks8995; - - ks8995 = dev_get_drvdata(&spi->dev); - sysfs_remove_bin_file(&spi->dev.kobj, &ks8995_registers_attr); - - dev_set_drvdata(&spi->dev, NULL); - kfree(ks8995); - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static struct spi_driver ks8995_driver = { - .driver = { - .name = "spi-ks8995", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = ks8995_probe, - .remove = __devexit_p(ks8995_remove), -}; - -static int __init ks8995_init(void) -{ - printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); - - return spi_register_driver(&ks8995_driver); -} -module_init(ks8995_init); - -static void __exit ks8995_exit(void) -{ - spi_unregister_driver(&ks8995_driver); -} -module_exit(ks8995_exit); - -MODULE_DESCRIPTION(DRV_DESC); -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/net/phy/ste10Xp.c b/ANDROID_3.4.5/drivers/net/phy/ste10Xp.c deleted file mode 100644 index 187a2fa8..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/ste10Xp.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * drivers/net/phy/ste10Xp.c - * - * Driver for STMicroelectronics STe10Xp PHYs - * - * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> - * - * Copyright (c) 2008 STMicroelectronics Limited - * - * 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/module.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/moduleparam.h> -#include <linux/interrupt.h> -#include <linux/netdevice.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/phy.h> - -#define MII_XCIIS 0x11 /* Configuration Info IRQ & Status Reg */ -#define MII_XIE 0x12 /* Interrupt Enable Register */ -#define MII_XIE_DEFAULT_MASK 0x0070 /* ANE complete, Remote Fault, Link Down */ - -#define STE101P_PHY_ID 0x00061c50 -#define STE100P_PHY_ID 0x1c040011 - -static int ste10Xp_config_init(struct phy_device *phydev) -{ - int value, err; - - /* Software Reset PHY */ - value = phy_read(phydev, MII_BMCR); - if (value < 0) - return value; - - value |= BMCR_RESET; - err = phy_write(phydev, MII_BMCR, value); - if (err < 0) - return err; - - do { - value = phy_read(phydev, MII_BMCR); - } while (value & BMCR_RESET); - - return 0; -} - -static int ste10Xp_config_intr(struct phy_device *phydev) -{ - int err, value; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { - /* Enable all STe101P interrupts (PR12) */ - err = phy_write(phydev, MII_XIE, MII_XIE_DEFAULT_MASK); - /* clear any pending interrupts */ - if (err == 0) { - value = phy_read(phydev, MII_XCIIS); - if (value < 0) - err = value; - } - } else - err = phy_write(phydev, MII_XIE, 0); - - return err; -} - -static int ste10Xp_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, MII_XCIIS); - if (err < 0) - return err; - - return 0; -} - -static struct phy_driver ste101p_pdriver = { - .phy_id = STE101P_PHY_ID, - .phy_id_mask = 0xfffffff0, - .name = "STe101p", - .features = PHY_BASIC_FEATURES | SUPPORTED_Pause, - .flags = PHY_HAS_INTERRUPT, - .config_init = ste10Xp_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = ste10Xp_ack_interrupt, - .config_intr = ste10Xp_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, - .driver = {.owner = THIS_MODULE,} -}; - -static struct phy_driver ste100p_pdriver = { - .phy_id = STE100P_PHY_ID, - .phy_id_mask = 0xffffffff, - .name = "STe100p", - .features = PHY_BASIC_FEATURES | SUPPORTED_Pause, - .flags = PHY_HAS_INTERRUPT, - .config_init = ste10Xp_config_init, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - .ack_interrupt = ste10Xp_ack_interrupt, - .config_intr = ste10Xp_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, - .driver = {.owner = THIS_MODULE,} -}; - -static int __init ste10Xp_init(void) -{ - int retval; - - retval = phy_driver_register(&ste100p_pdriver); - if (retval < 0) - return retval; - return phy_driver_register(&ste101p_pdriver); -} - -static void __exit ste10Xp_exit(void) -{ - phy_driver_unregister(&ste100p_pdriver); - phy_driver_unregister(&ste101p_pdriver); -} - -module_init(ste10Xp_init); -module_exit(ste10Xp_exit); - -static struct mdio_device_id __maybe_unused ste10Xp_tbl[] = { - { STE101P_PHY_ID, 0xfffffff0 }, - { STE100P_PHY_ID, 0xffffffff }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, ste10Xp_tbl); - -MODULE_DESCRIPTION("STMicroelectronics STe10Xp PHY driver"); -MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/net/phy/vitesse.c b/ANDROID_3.4.5/drivers/net/phy/vitesse.c deleted file mode 100644 index 0ec8e09c..00000000 --- a/ANDROID_3.4.5/drivers/net/phy/vitesse.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Driver for Vitesse PHYs - * - * Author: Kriston Carson - * - * Copyright (c) 2005, 2009 Freescale Semiconductor, 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/kernel.h> -#include <linux/module.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <linux/phy.h> - -/* Vitesse Extended Control Register 1 */ -#define MII_VSC8244_EXT_CON1 0x17 -#define MII_VSC8244_EXTCON1_INIT 0x0000 -#define MII_VSC8244_EXTCON1_TX_SKEW_MASK 0x0c00 -#define MII_VSC8244_EXTCON1_RX_SKEW_MASK 0x0300 -#define MII_VSC8244_EXTCON1_TX_SKEW 0x0800 -#define MII_VSC8244_EXTCON1_RX_SKEW 0x0200 - -/* Vitesse Interrupt Mask Register */ -#define MII_VSC8244_IMASK 0x19 -#define MII_VSC8244_IMASK_IEN 0x8000 -#define MII_VSC8244_IMASK_SPEED 0x4000 -#define MII_VSC8244_IMASK_LINK 0x2000 -#define MII_VSC8244_IMASK_DUPLEX 0x1000 -#define MII_VSC8244_IMASK_MASK 0xf000 - -#define MII_VSC8221_IMASK_MASK 0xa000 - -/* Vitesse Interrupt Status Register */ -#define MII_VSC8244_ISTAT 0x1a -#define MII_VSC8244_ISTAT_STATUS 0x8000 -#define MII_VSC8244_ISTAT_SPEED 0x4000 -#define MII_VSC8244_ISTAT_LINK 0x2000 -#define MII_VSC8244_ISTAT_DUPLEX 0x1000 - -/* Vitesse Auxiliary Control/Status Register */ -#define MII_VSC8244_AUX_CONSTAT 0x1c -#define MII_VSC8244_AUXCONSTAT_INIT 0x0000 -#define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 -#define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 -#define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 -#define MII_VSC8244_AUXCONSTAT_100 0x0008 - -#define MII_VSC8221_AUXCONSTAT_INIT 0x0004 /* need to set this bit? */ -#define MII_VSC8221_AUXCONSTAT_RESERVED 0x0004 - -#define PHY_ID_VSC8244 0x000fc6c0 -#define PHY_ID_VSC8221 0x000fc550 - -MODULE_DESCRIPTION("Vitesse PHY driver"); -MODULE_AUTHOR("Kriston Carson"); -MODULE_LICENSE("GPL"); - -int vsc824x_add_skew(struct phy_device *phydev) -{ - int err; - int extcon; - - extcon = phy_read(phydev, MII_VSC8244_EXT_CON1); - - if (extcon < 0) - return extcon; - - extcon &= ~(MII_VSC8244_EXTCON1_TX_SKEW_MASK | - MII_VSC8244_EXTCON1_RX_SKEW_MASK); - - extcon |= (MII_VSC8244_EXTCON1_TX_SKEW | - MII_VSC8244_EXTCON1_RX_SKEW); - - err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon); - - return err; -} -EXPORT_SYMBOL(vsc824x_add_skew); - -static int vsc824x_config_init(struct phy_device *phydev) -{ - int err; - - err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, - MII_VSC8244_AUXCONSTAT_INIT); - if (err < 0) - return err; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) - err = vsc824x_add_skew(phydev); - - return err; -} - -static int vsc824x_ack_interrupt(struct phy_device *phydev) -{ - int err = 0; - - /* - * Don't bother to ACK the interrupts if interrupts - * are disabled. The 824x cannot clear the interrupts - * if they are disabled. - */ - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_read(phydev, MII_VSC8244_ISTAT); - - return (err < 0) ? err : 0; -} - -static int vsc82xx_config_intr(struct phy_device *phydev) -{ - int err; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_VSC8244_IMASK, - phydev->drv->phy_id == PHY_ID_VSC8244 ? - MII_VSC8244_IMASK_MASK : - MII_VSC8221_IMASK_MASK); - else { - /* - * The Vitesse PHY cannot clear the interrupt - * once it has disabled them, so we clear them first - */ - err = phy_read(phydev, MII_VSC8244_ISTAT); - - if (err < 0) - return err; - - err = phy_write(phydev, MII_VSC8244_IMASK, 0); - } - - return err; -} - -/* Vitesse 824x */ -static struct phy_driver vsc8244_driver = { - .phy_id = PHY_ID_VSC8244, - .name = "Vitesse VSC8244", - .phy_id_mask = 0x000fffc0, - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &vsc824x_config_init, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &vsc824x_ack_interrupt, - .config_intr = &vsc82xx_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int vsc8221_config_init(struct phy_device *phydev) -{ - int err; - - err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, - MII_VSC8221_AUXCONSTAT_INIT); - return err; - - /* Perhaps we should set EXT_CON1 based on the interface? - Options are 802.3Z SerDes or SGMII */ -} - -/* Vitesse 8221 */ -static struct phy_driver vsc8221_driver = { - .phy_id = PHY_ID_VSC8221, - .phy_id_mask = 0x000ffff0, - .name = "Vitesse VSC8221", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &vsc8221_config_init, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &vsc824x_ack_interrupt, - .config_intr = &vsc82xx_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init vsc82xx_init(void) -{ - int err; - - err = phy_driver_register(&vsc8244_driver); - if (err < 0) - return err; - err = phy_driver_register(&vsc8221_driver); - if (err < 0) - phy_driver_unregister(&vsc8244_driver); - return err; -} - -static void __exit vsc82xx_exit(void) -{ - phy_driver_unregister(&vsc8244_driver); - phy_driver_unregister(&vsc8221_driver); -} - -module_init(vsc82xx_init); -module_exit(vsc82xx_exit); - -static struct mdio_device_id __maybe_unused vitesse_tbl[] = { - { PHY_ID_VSC8244, 0x000fffc0 }, - { PHY_ID_VSC8221, 0x000ffff0 }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, vitesse_tbl); |