1 /* 2 * drivers/net/phy/smsc.c 3 * 4 * Driver for SMSC PHYs 5 * 6 * Author: Herbert Valerio Riedel 7 * 8 * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org> 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the 12 * Free Software Foundation; either version 2 of the License, or (at your 13 * option) any later version. 14 * 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/mii.h> 20 #include <linux/ethtool.h> 21 #include <linux/phy.h> 22 #include <linux/netdevice.h> 23 24 #define MII_LAN83C185_ISF 29 /* Interrupt Source Flags */ 25 #define MII_LAN83C185_IM 30 /* Interrupt Mask */ 26 27 #define MII_LAN83C185_ISF_INT1 (1<<1) /* Auto-Negotiation Page Received */ 28 #define MII_LAN83C185_ISF_INT2 (1<<2) /* Parallel Detection Fault */ 29 #define MII_LAN83C185_ISF_INT3 (1<<3) /* Auto-Negotiation LP Ack */ 30 #define MII_LAN83C185_ISF_INT4 (1<<4) /* Link Down */ 31 #define MII_LAN83C185_ISF_INT5 (1<<5) /* Remote Fault Detected */ 32 #define MII_LAN83C185_ISF_INT6 (1<<6) /* Auto-Negotiation complete */ 33 #define MII_LAN83C185_ISF_INT7 (1<<7) /* ENERGYON */ 34 35 #define MII_LAN83C185_ISF_INT_ALL (0x0e) 36 37 #define MII_LAN83C185_ISF_INT_PHYLIB_EVENTS \ 38 (MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4) 39 40 41 static int lan83c185_config_intr(struct phy_device *phydev) 42 { 43 int rc = phy_write (phydev, MII_LAN83C185_IM, 44 ((PHY_INTERRUPT_ENABLED == phydev->interrupts) 45 ? MII_LAN83C185_ISF_INT_PHYLIB_EVENTS 46 : 0)); 47 48 return rc < 0 ? rc : 0; 49 } 50 51 static int lan83c185_ack_interrupt(struct phy_device *phydev) 52 { 53 int rc = phy_read (phydev, MII_LAN83C185_ISF); 54 55 return rc < 0 ? rc : 0; 56 } 57 58 static int lan83c185_config_init(struct phy_device *phydev) 59 { 60 return lan83c185_ack_interrupt (phydev); 61 } 62 63 64 static struct phy_driver lan83c185_driver = { 65 .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */ 66 .phy_id_mask = 0xfffffff0, 67 .name = "SMSC LAN83C185", 68 69 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause 70 | SUPPORTED_Asym_Pause), 71 .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, 72 73 /* basic functions */ 74 .config_aneg = genphy_config_aneg, 75 .read_status = genphy_read_status, 76 .config_init = lan83c185_config_init, 77 78 /* IRQ related */ 79 .ack_interrupt = lan83c185_ack_interrupt, 80 .config_intr = lan83c185_config_intr, 81 82 .driver = { .owner = THIS_MODULE, } 83 }; 84 85 static int __init smsc_init(void) 86 { 87 return phy_driver_register (&lan83c185_driver); 88 } 89 90 static void __exit smsc_exit(void) 91 { 92 phy_driver_unregister (&lan83c185_driver); 93 } 94 95 MODULE_DESCRIPTION("SMSC PHY driver"); 96 MODULE_AUTHOR("Herbert Valerio Riedel"); 97 MODULE_LICENSE("GPL"); 98 99 module_init(smsc_init); 100 module_exit(smsc_exit); 101