Blame view
drivers/net/phy/aquantia.c
4.95 KB
bee8259dd net: phy: add dri... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/* * Driver for Aquantia PHY * * Author: Shaohui Xie <Shaohui.Xie@freescale.com> * * Copyright 2015 Freescale Semiconductor, Inc. * * 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/kernel.h> #include <linux/module.h> #include <linux/delay.h> #include <linux/mii.h> #include <linux/ethtool.h> #include <linux/phy.h> #include <linux/mdio.h> #define PHY_ID_AQ1202 0x03a1b445 #define PHY_ID_AQ2104 0x03a1b460 #define PHY_ID_AQR105 0x03a1b4a2 |
547412fe0 net: phy: aquanti... |
24 25 |
#define PHY_ID_AQR106 0x03a1b4d0 #define PHY_ID_AQR107 0x03a1b4e0 |
bee8259dd net: phy: add dri... |
26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#define PHY_ID_AQR405 0x03a1b4b0 #define PHY_AQUANTIA_FEATURES (SUPPORTED_10000baseT_Full | \ SUPPORTED_1000baseT_Full | \ SUPPORTED_100baseT_Full | \ PHY_DEFAULT_FEATURES) static int aquantia_config_aneg(struct phy_device *phydev) { phydev->supported = PHY_AQUANTIA_FEATURES; phydev->advertising = phydev->supported; return 0; } |
54cf7be99 net: phy: add int... |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
static int aquantia_config_intr(struct phy_device *phydev) { int err; if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 1); if (err < 0) return err; err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 1); if (err < 0) return err; err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0x1001); } else { err = phy_write_mmd(phydev, MDIO_MMD_AN, 0xd401, 0); if (err < 0) return err; err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff00, 0); if (err < 0) return err; err = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xff01, 0); } return err; } static int aquantia_ack_interrupt(struct phy_device *phydev) { int reg; reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xcc01); return (reg < 0) ? reg : 0; } |
bee8259dd net: phy: add dri... |
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
static int aquantia_read_status(struct phy_device *phydev) { int reg; reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); if (reg & MDIO_STAT1_LSTATUS) phydev->link = 1; else phydev->link = 0; reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800); mdelay(10); reg = phy_read_mmd(phydev, MDIO_MMD_AN, 0xc800); switch (reg) { case 0x9: phydev->speed = SPEED_2500; break; case 0x5: phydev->speed = SPEED_1000; break; case 0x3: phydev->speed = SPEED_100; break; case 0x7: default: phydev->speed = SPEED_10000; break; } phydev->duplex = DUPLEX_FULL; return 0; } static struct phy_driver aquantia_driver[] = { { .phy_id = PHY_ID_AQ1202, .phy_id_mask = 0xfffffff0, .name = "Aquantia AQ1202", .features = PHY_AQUANTIA_FEATURES, |
54cf7be99 net: phy: add int... |
117 |
.flags = PHY_HAS_INTERRUPT, |
6ed33d3a0 net: phy: aquanti... |
118 |
.aneg_done = genphy_c45_aneg_done, |
bee8259dd net: phy: add dri... |
119 |
.config_aneg = aquantia_config_aneg, |
54cf7be99 net: phy: add int... |
120 121 |
.config_intr = aquantia_config_intr, .ack_interrupt = aquantia_ack_interrupt, |
bee8259dd net: phy: add dri... |
122 |
.read_status = aquantia_read_status, |
bee8259dd net: phy: add dri... |
123 124 125 126 127 128 |
}, { .phy_id = PHY_ID_AQ2104, .phy_id_mask = 0xfffffff0, .name = "Aquantia AQ2104", .features = PHY_AQUANTIA_FEATURES, |
54cf7be99 net: phy: add int... |
129 |
.flags = PHY_HAS_INTERRUPT, |
6ed33d3a0 net: phy: aquanti... |
130 |
.aneg_done = genphy_c45_aneg_done, |
bee8259dd net: phy: add dri... |
131 |
.config_aneg = aquantia_config_aneg, |
54cf7be99 net: phy: add int... |
132 133 |
.config_intr = aquantia_config_intr, .ack_interrupt = aquantia_ack_interrupt, |
bee8259dd net: phy: add dri... |
134 |
.read_status = aquantia_read_status, |
bee8259dd net: phy: add dri... |
135 136 137 138 139 140 |
}, { .phy_id = PHY_ID_AQR105, .phy_id_mask = 0xfffffff0, .name = "Aquantia AQR105", .features = PHY_AQUANTIA_FEATURES, |
54cf7be99 net: phy: add int... |
141 |
.flags = PHY_HAS_INTERRUPT, |
6ed33d3a0 net: phy: aquanti... |
142 |
.aneg_done = genphy_c45_aneg_done, |
bee8259dd net: phy: add dri... |
143 |
.config_aneg = aquantia_config_aneg, |
54cf7be99 net: phy: add int... |
144 145 |
.config_intr = aquantia_config_intr, .ack_interrupt = aquantia_ack_interrupt, |
bee8259dd net: phy: add dri... |
146 |
.read_status = aquantia_read_status, |
bee8259dd net: phy: add dri... |
147 148 |
}, { |
547412fe0 net: phy: aquanti... |
149 150 151 152 153 |
.phy_id = PHY_ID_AQR106, .phy_id_mask = 0xfffffff0, .name = "Aquantia AQR106", .features = PHY_AQUANTIA_FEATURES, .flags = PHY_HAS_INTERRUPT, |
6ed33d3a0 net: phy: aquanti... |
154 |
.aneg_done = genphy_c45_aneg_done, |
547412fe0 net: phy: aquanti... |
155 156 157 158 159 160 161 162 163 164 165 |
.config_aneg = aquantia_config_aneg, .config_intr = aquantia_config_intr, .ack_interrupt = aquantia_ack_interrupt, .read_status = aquantia_read_status, }, { .phy_id = PHY_ID_AQR107, .phy_id_mask = 0xfffffff0, .name = "Aquantia AQR107", .features = PHY_AQUANTIA_FEATURES, .flags = PHY_HAS_INTERRUPT, |
6ed33d3a0 net: phy: aquanti... |
166 |
.aneg_done = genphy_c45_aneg_done, |
547412fe0 net: phy: aquanti... |
167 168 169 170 171 172 |
.config_aneg = aquantia_config_aneg, .config_intr = aquantia_config_intr, .ack_interrupt = aquantia_ack_interrupt, .read_status = aquantia_read_status, }, { |
bee8259dd net: phy: add dri... |
173 174 175 176 |
.phy_id = PHY_ID_AQR405, .phy_id_mask = 0xfffffff0, .name = "Aquantia AQR405", .features = PHY_AQUANTIA_FEATURES, |
54cf7be99 net: phy: add int... |
177 |
.flags = PHY_HAS_INTERRUPT, |
6ed33d3a0 net: phy: aquanti... |
178 |
.aneg_done = genphy_c45_aneg_done, |
bee8259dd net: phy: add dri... |
179 |
.config_aneg = aquantia_config_aneg, |
54cf7be99 net: phy: add int... |
180 181 |
.config_intr = aquantia_config_intr, .ack_interrupt = aquantia_ack_interrupt, |
bee8259dd net: phy: add dri... |
182 |
.read_status = aquantia_read_status, |
bee8259dd net: phy: add dri... |
183 184 |
}, }; |
fb0801dcc net: phy: aquanti... |
185 |
module_phy_driver(aquantia_driver); |
bee8259dd net: phy: add dri... |
186 187 188 189 190 |
static struct mdio_device_id __maybe_unused aquantia_tbl[] = { { PHY_ID_AQ1202, 0xfffffff0 }, { PHY_ID_AQ2104, 0xfffffff0 }, { PHY_ID_AQR105, 0xfffffff0 }, |
547412fe0 net: phy: aquanti... |
191 192 |
{ PHY_ID_AQR106, 0xfffffff0 }, { PHY_ID_AQR107, 0xfffffff0 }, |
bee8259dd net: phy: add dri... |
193 194 195 196 197 198 199 200 201 |
{ PHY_ID_AQR405, 0xfffffff0 }, { } }; MODULE_DEVICE_TABLE(mdio, aquantia_tbl); MODULE_DESCRIPTION("Aquantia PHY driver"); MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>"); MODULE_LICENSE("GPL v2"); |