18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * drivers/net/phy/et1011c.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Driver for LSI ET1011C PHYs 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Author: Chaithrika U S 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Copyright (c) 2008 Texas Instruments 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include <linux/string.h> 138c2ecf20Sopenharmony_ci#include <linux/errno.h> 148c2ecf20Sopenharmony_ci#include <linux/unistd.h> 158c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 168c2ecf20Sopenharmony_ci#include <linux/init.h> 178c2ecf20Sopenharmony_ci#include <linux/delay.h> 188c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 198c2ecf20Sopenharmony_ci#include <linux/etherdevice.h> 208c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 218c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 228c2ecf20Sopenharmony_ci#include <linux/mm.h> 238c2ecf20Sopenharmony_ci#include <linux/module.h> 248c2ecf20Sopenharmony_ci#include <linux/mii.h> 258c2ecf20Sopenharmony_ci#include <linux/ethtool.h> 268c2ecf20Sopenharmony_ci#include <linux/phy.h> 278c2ecf20Sopenharmony_ci#include <linux/io.h> 288c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 298c2ecf20Sopenharmony_ci#include <asm/irq.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define ET1011C_STATUS_REG (0x1A) 328c2ecf20Sopenharmony_ci#define ET1011C_CONFIG_REG (0x16) 338c2ecf20Sopenharmony_ci#define ET1011C_SPEED_MASK (0x0300) 348c2ecf20Sopenharmony_ci#define ET1011C_GIGABIT_SPEED (0x0200) 358c2ecf20Sopenharmony_ci#define ET1011C_TX_FIFO_MASK (0x3000) 368c2ecf20Sopenharmony_ci#define ET1011C_TX_FIFO_DEPTH_8 (0x0000) 378c2ecf20Sopenharmony_ci#define ET1011C_TX_FIFO_DEPTH_16 (0x1000) 388c2ecf20Sopenharmony_ci#define ET1011C_INTERFACE_MASK (0x0007) 398c2ecf20Sopenharmony_ci#define ET1011C_GMII_INTERFACE (0x0002) 408c2ecf20Sopenharmony_ci#define ET1011C_SYS_CLK_EN (0x01 << 4) 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("LSI ET1011C PHY driver"); 448c2ecf20Sopenharmony_ciMODULE_AUTHOR("Chaithrika U S"); 458c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int et1011c_config_aneg(struct phy_device *phydev) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci int ctl = 0; 508c2ecf20Sopenharmony_ci ctl = phy_read(phydev, MII_BMCR); 518c2ecf20Sopenharmony_ci if (ctl < 0) 528c2ecf20Sopenharmony_ci return ctl; 538c2ecf20Sopenharmony_ci ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | 548c2ecf20Sopenharmony_ci BMCR_ANENABLE); 558c2ecf20Sopenharmony_ci /* First clear the PHY */ 568c2ecf20Sopenharmony_ci phy_write(phydev, MII_BMCR, ctl | BMCR_RESET); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci return genphy_config_aneg(phydev); 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic int et1011c_read_status(struct phy_device *phydev) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci int ret; 648c2ecf20Sopenharmony_ci u32 val; 658c2ecf20Sopenharmony_ci static int speed; 668c2ecf20Sopenharmony_ci ret = genphy_read_status(phydev); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (speed != phydev->speed) { 698c2ecf20Sopenharmony_ci speed = phydev->speed; 708c2ecf20Sopenharmony_ci val = phy_read(phydev, ET1011C_STATUS_REG); 718c2ecf20Sopenharmony_ci if ((val & ET1011C_SPEED_MASK) == 728c2ecf20Sopenharmony_ci ET1011C_GIGABIT_SPEED) { 738c2ecf20Sopenharmony_ci val = phy_read(phydev, ET1011C_CONFIG_REG); 748c2ecf20Sopenharmony_ci val &= ~ET1011C_TX_FIFO_MASK; 758c2ecf20Sopenharmony_ci phy_write(phydev, ET1011C_CONFIG_REG, val\ 768c2ecf20Sopenharmony_ci | ET1011C_GMII_INTERFACE\ 778c2ecf20Sopenharmony_ci | ET1011C_SYS_CLK_EN\ 788c2ecf20Sopenharmony_ci | ET1011C_TX_FIFO_DEPTH_16); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci return ret; 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic struct phy_driver et1011c_driver[] = { { 868c2ecf20Sopenharmony_ci .phy_id = 0x0282f014, 878c2ecf20Sopenharmony_ci .name = "ET1011C", 888c2ecf20Sopenharmony_ci .phy_id_mask = 0xfffffff0, 898c2ecf20Sopenharmony_ci /* PHY_GBIT_FEATURES */ 908c2ecf20Sopenharmony_ci .config_aneg = et1011c_config_aneg, 918c2ecf20Sopenharmony_ci .read_status = et1011c_read_status, 928c2ecf20Sopenharmony_ci} }; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cimodule_phy_driver(et1011c_driver); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistatic struct mdio_device_id __maybe_unused et1011c_tbl[] = { 978c2ecf20Sopenharmony_ci { 0x0282f014, 0xfffffff0 }, 988c2ecf20Sopenharmony_ci { } 998c2ecf20Sopenharmony_ci}; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(mdio, et1011c_tbl); 102