]> Git Repo - linux.git/blob - drivers/net/phy/aquantia_main.c
Merge tag 'mlx5-fixes-2019-03-11' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / net / phy / aquantia_main.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for Aquantia PHY
4  *
5  * Author: Shaohui Xie <[email protected]>
6  *
7  * Copyright 2015 Freescale Semiconductor, Inc.
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/delay.h>
13 #include <linux/phy.h>
14
15 #include "aquantia.h"
16
17 #define PHY_ID_AQ1202   0x03a1b445
18 #define PHY_ID_AQ2104   0x03a1b460
19 #define PHY_ID_AQR105   0x03a1b4a2
20 #define PHY_ID_AQR106   0x03a1b4d0
21 #define PHY_ID_AQR107   0x03a1b4e0
22 #define PHY_ID_AQCS109  0x03a1b5c2
23 #define PHY_ID_AQR405   0x03a1b4b0
24
25 #define MDIO_AN_VEND_PROV                       0xc400
26 #define MDIO_AN_VEND_PROV_1000BASET_FULL        BIT(15)
27 #define MDIO_AN_VEND_PROV_1000BASET_HALF        BIT(14)
28
29 #define MDIO_AN_TX_VEND_STATUS1                 0xc800
30 #define MDIO_AN_TX_VEND_STATUS1_10BASET         (0x0 << 1)
31 #define MDIO_AN_TX_VEND_STATUS1_100BASETX       (0x1 << 1)
32 #define MDIO_AN_TX_VEND_STATUS1_1000BASET       (0x2 << 1)
33 #define MDIO_AN_TX_VEND_STATUS1_10GBASET        (0x3 << 1)
34 #define MDIO_AN_TX_VEND_STATUS1_2500BASET       (0x4 << 1)
35 #define MDIO_AN_TX_VEND_STATUS1_5000BASET       (0x5 << 1)
36 #define MDIO_AN_TX_VEND_STATUS1_RATE_MASK       (0x7 << 1)
37 #define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX     BIT(0)
38
39 #define MDIO_AN_TX_VEND_INT_STATUS2             0xcc01
40
41 #define MDIO_AN_TX_VEND_INT_MASK2               0xd401
42 #define MDIO_AN_TX_VEND_INT_MASK2_LINK          BIT(0)
43
44 #define MDIO_AN_RX_LP_STAT1                     0xe820
45 #define MDIO_AN_RX_LP_STAT1_1000BASET_FULL      BIT(15)
46 #define MDIO_AN_RX_LP_STAT1_1000BASET_HALF      BIT(14)
47
48 /* Vendor specific 1, MDIO_MMD_VEND1 */
49 #define VEND1_GLOBAL_INT_STD_STATUS             0xfc00
50 #define VEND1_GLOBAL_INT_VEND_STATUS            0xfc01
51
52 #define VEND1_GLOBAL_INT_STD_MASK               0xff00
53 #define VEND1_GLOBAL_INT_STD_MASK_PMA1          BIT(15)
54 #define VEND1_GLOBAL_INT_STD_MASK_PMA2          BIT(14)
55 #define VEND1_GLOBAL_INT_STD_MASK_PCS1          BIT(13)
56 #define VEND1_GLOBAL_INT_STD_MASK_PCS2          BIT(12)
57 #define VEND1_GLOBAL_INT_STD_MASK_PCS3          BIT(11)
58 #define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1       BIT(10)
59 #define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2       BIT(9)
60 #define VEND1_GLOBAL_INT_STD_MASK_AN1           BIT(8)
61 #define VEND1_GLOBAL_INT_STD_MASK_AN2           BIT(7)
62 #define VEND1_GLOBAL_INT_STD_MASK_GBE           BIT(6)
63 #define VEND1_GLOBAL_INT_STD_MASK_ALL           BIT(0)
64
65 #define VEND1_GLOBAL_INT_VEND_MASK              0xff01
66 #define VEND1_GLOBAL_INT_VEND_MASK_PMA          BIT(15)
67 #define VEND1_GLOBAL_INT_VEND_MASK_PCS          BIT(14)
68 #define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS       BIT(13)
69 #define VEND1_GLOBAL_INT_VEND_MASK_AN           BIT(12)
70 #define VEND1_GLOBAL_INT_VEND_MASK_GBE          BIT(11)
71 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1      BIT(2)
72 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2      BIT(1)
73 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3      BIT(0)
74
75 static int aqr_config_aneg(struct phy_device *phydev)
76 {
77         bool changed = false;
78         u16 reg;
79         int ret;
80
81         if (phydev->autoneg == AUTONEG_DISABLE)
82                 return genphy_c45_pma_setup_forced(phydev);
83
84         ret = genphy_c45_an_config_aneg(phydev);
85         if (ret < 0)
86                 return ret;
87         if (ret > 0)
88                 changed = true;
89
90         /* Clause 45 has no standardized support for 1000BaseT, therefore
91          * use vendor registers for this mode.
92          */
93         reg = 0;
94         if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
95                               phydev->advertising))
96                 reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
97
98         if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
99                               phydev->advertising))
100                 reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
101
102         ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
103                                      MDIO_AN_VEND_PROV_1000BASET_HALF |
104                                      MDIO_AN_VEND_PROV_1000BASET_FULL, reg);
105         if (ret < 0)
106                 return ret;
107         if (ret > 0)
108                 changed = true;
109
110         return genphy_c45_check_and_restart_aneg(phydev, changed);
111 }
112
113 static int aqr_config_intr(struct phy_device *phydev)
114 {
115         int err;
116
117         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
118                 err = phy_write_mmd(phydev, MDIO_MMD_AN,
119                                     MDIO_AN_TX_VEND_INT_MASK2,
120                                     MDIO_AN_TX_VEND_INT_MASK2_LINK);
121                 if (err < 0)
122                         return err;
123
124                 err = phy_write_mmd(phydev, MDIO_MMD_VEND1,
125                                     VEND1_GLOBAL_INT_STD_MASK,
126                                     VEND1_GLOBAL_INT_STD_MASK_ALL);
127                 if (err < 0)
128                         return err;
129
130                 err = phy_write_mmd(phydev, MDIO_MMD_VEND1,
131                                     VEND1_GLOBAL_INT_VEND_MASK,
132                                     VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
133                                     VEND1_GLOBAL_INT_VEND_MASK_AN);
134         } else {
135                 err = phy_write_mmd(phydev, MDIO_MMD_AN,
136                                     MDIO_AN_TX_VEND_INT_MASK2, 0);
137                 if (err < 0)
138                         return err;
139
140                 err = phy_write_mmd(phydev, MDIO_MMD_VEND1,
141                                     VEND1_GLOBAL_INT_STD_MASK, 0);
142                 if (err < 0)
143                         return err;
144
145                 err = phy_write_mmd(phydev, MDIO_MMD_VEND1,
146                                     VEND1_GLOBAL_INT_VEND_MASK, 0);
147         }
148
149         return err;
150 }
151
152 static int aqr_ack_interrupt(struct phy_device *phydev)
153 {
154         int reg;
155
156         reg = phy_read_mmd(phydev, MDIO_MMD_AN,
157                            MDIO_AN_TX_VEND_INT_STATUS2);
158         return (reg < 0) ? reg : 0;
159 }
160
161 static int aqr_read_status(struct phy_device *phydev)
162 {
163         int val;
164
165         if (phydev->autoneg == AUTONEG_ENABLE) {
166                 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
167                 if (val < 0)
168                         return val;
169
170                 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
171                                  phydev->lp_advertising,
172                                  val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);
173                 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
174                                  phydev->lp_advertising,
175                                  val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);
176         }
177
178         return genphy_c45_read_status(phydev);
179 }
180
181 static int aqcs109_config_init(struct phy_device *phydev)
182 {
183         /* AQCS109 belongs to a chip family partially supporting 10G and 5G.
184          * PMA speed ability bits are the same for all members of the family,
185          * AQCS109 however supports speeds up to 2.5G only.
186          */
187         return phy_set_max_speed(phydev, SPEED_2500);
188 }
189
190 static struct phy_driver aqr_driver[] = {
191 {
192         PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
193         .name           = "Aquantia AQ1202",
194         .aneg_done      = genphy_c45_aneg_done,
195         .get_features   = genphy_c45_pma_read_abilities,
196         .config_aneg    = aqr_config_aneg,
197         .config_intr    = aqr_config_intr,
198         .ack_interrupt  = aqr_ack_interrupt,
199         .read_status    = aqr_read_status,
200 },
201 {
202         PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),
203         .name           = "Aquantia AQ2104",
204         .aneg_done      = genphy_c45_aneg_done,
205         .get_features   = genphy_c45_pma_read_abilities,
206         .config_aneg    = aqr_config_aneg,
207         .config_intr    = aqr_config_intr,
208         .ack_interrupt  = aqr_ack_interrupt,
209         .read_status    = aqr_read_status,
210 },
211 {
212         PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
213         .name           = "Aquantia AQR105",
214         .aneg_done      = genphy_c45_aneg_done,
215         .get_features   = genphy_c45_pma_read_abilities,
216         .config_aneg    = aqr_config_aneg,
217         .config_intr    = aqr_config_intr,
218         .ack_interrupt  = aqr_ack_interrupt,
219         .read_status    = aqr_read_status,
220 },
221 {
222         PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
223         .name           = "Aquantia AQR106",
224         .aneg_done      = genphy_c45_aneg_done,
225         .get_features   = genphy_c45_pma_read_abilities,
226         .config_aneg    = aqr_config_aneg,
227         .config_intr    = aqr_config_intr,
228         .ack_interrupt  = aqr_ack_interrupt,
229         .read_status    = aqr_read_status,
230 },
231 {
232         PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
233         .name           = "Aquantia AQR107",
234         .aneg_done      = genphy_c45_aneg_done,
235         .get_features   = genphy_c45_pma_read_abilities,
236         .probe          = aqr_hwmon_probe,
237         .config_aneg    = aqr_config_aneg,
238         .config_intr    = aqr_config_intr,
239         .ack_interrupt  = aqr_ack_interrupt,
240         .read_status    = aqr_read_status,
241 },
242 {
243         PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
244         .name           = "Aquantia AQCS109",
245         .aneg_done      = genphy_c45_aneg_done,
246         .get_features   = genphy_c45_pma_read_abilities,
247         .probe          = aqr_hwmon_probe,
248         .config_init    = aqcs109_config_init,
249         .config_aneg    = aqr_config_aneg,
250         .config_intr    = aqr_config_intr,
251         .ack_interrupt  = aqr_ack_interrupt,
252         .read_status    = aqr_read_status,
253 },
254 {
255         PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
256         .name           = "Aquantia AQR405",
257         .aneg_done      = genphy_c45_aneg_done,
258         .get_features   = genphy_c45_pma_read_abilities,
259         .config_aneg    = aqr_config_aneg,
260         .config_intr    = aqr_config_intr,
261         .ack_interrupt  = aqr_ack_interrupt,
262         .read_status    = aqr_read_status,
263 },
264 };
265
266 module_phy_driver(aqr_driver);
267
268 static struct mdio_device_id __maybe_unused aqr_tbl[] = {
269         { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
270         { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
271         { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
272         { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
273         { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
274         { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
275         { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
276         { }
277 };
278
279 MODULE_DEVICE_TABLE(mdio, aqr_tbl);
280
281 MODULE_DESCRIPTION("Aquantia PHY driver");
282 MODULE_AUTHOR("Shaohui Xie <[email protected]>");
283 MODULE_LICENSE("GPL v2");
This page took 0.044004 seconds and 4 git commands to generate.