]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/net/phy/aquantia_main.c
330ee02abcad99977ba295aa32e320b793736418
[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 <Shaohui.Xie@freescale.com>
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/bitfield.h>
14 #include <linux/phy.h>
15
16 #include "aquantia.h"
17
18 #define PHY_ID_AQ1202   0x03a1b445
19 #define PHY_ID_AQ2104   0x03a1b460
20 #define PHY_ID_AQR105   0x03a1b4a2
21 #define PHY_ID_AQR106   0x03a1b4d0
22 #define PHY_ID_AQR107   0x03a1b4e0
23 #define PHY_ID_AQCS109  0x03a1b5c2
24 #define PHY_ID_AQR405   0x03a1b4b0
25
26 #define MDIO_PHYXS_VEND_IF_STATUS               0xe812
27 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK     GENMASK(7, 3)
28 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR       0
29 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI      2
30 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII    6
31 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII  10
32
33 #define MDIO_AN_VEND_PROV                       0xc400
34 #define MDIO_AN_VEND_PROV_1000BASET_FULL        BIT(15)
35 #define MDIO_AN_VEND_PROV_1000BASET_HALF        BIT(14)
36 #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN          BIT(4)
37 #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK        GENMASK(3, 0)
38 #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT        4
39
40 #define MDIO_AN_TX_VEND_STATUS1                 0xc800
41 #define MDIO_AN_TX_VEND_STATUS1_RATE_MASK       GENMASK(3, 1)
42 #define MDIO_AN_TX_VEND_STATUS1_10BASET         0
43 #define MDIO_AN_TX_VEND_STATUS1_100BASETX       1
44 #define MDIO_AN_TX_VEND_STATUS1_1000BASET       2
45 #define MDIO_AN_TX_VEND_STATUS1_10GBASET        3
46 #define MDIO_AN_TX_VEND_STATUS1_2500BASET       4
47 #define MDIO_AN_TX_VEND_STATUS1_5000BASET       5
48 #define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX     BIT(0)
49
50 #define MDIO_AN_TX_VEND_INT_STATUS1             0xcc00
51 #define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT   BIT(1)
52
53 #define MDIO_AN_TX_VEND_INT_STATUS2             0xcc01
54
55 #define MDIO_AN_TX_VEND_INT_MASK2               0xd401
56 #define MDIO_AN_TX_VEND_INT_MASK2_LINK          BIT(0)
57
58 #define MDIO_AN_RX_LP_STAT1                     0xe820
59 #define MDIO_AN_RX_LP_STAT1_1000BASET_FULL      BIT(15)
60 #define MDIO_AN_RX_LP_STAT1_1000BASET_HALF      BIT(14)
61 #define MDIO_AN_RX_LP_STAT1_SHORT_REACH         BIT(13)
62 #define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT    BIT(12)
63 #define MDIO_AN_RX_LP_STAT1_AQ_PHY              BIT(2)
64
65 #define MDIO_AN_RX_LP_STAT4                     0xe823
66 #define MDIO_AN_RX_LP_STAT4_FW_MAJOR            GENMASK(15, 8)
67 #define MDIO_AN_RX_LP_STAT4_FW_MINOR            GENMASK(7, 0)
68
69 #define MDIO_AN_RX_VEND_STAT3                   0xe832
70 #define MDIO_AN_RX_VEND_STAT3_AFR               BIT(0)
71
72 /* Vendor specific 1, MDIO_MMD_VEND1 */
73 #define VEND1_GLOBAL_INT_STD_STATUS             0xfc00
74 #define VEND1_GLOBAL_INT_VEND_STATUS            0xfc01
75
76 #define VEND1_GLOBAL_INT_STD_MASK               0xff00
77 #define VEND1_GLOBAL_INT_STD_MASK_PMA1          BIT(15)
78 #define VEND1_GLOBAL_INT_STD_MASK_PMA2          BIT(14)
79 #define VEND1_GLOBAL_INT_STD_MASK_PCS1          BIT(13)
80 #define VEND1_GLOBAL_INT_STD_MASK_PCS2          BIT(12)
81 #define VEND1_GLOBAL_INT_STD_MASK_PCS3          BIT(11)
82 #define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1       BIT(10)
83 #define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2       BIT(9)
84 #define VEND1_GLOBAL_INT_STD_MASK_AN1           BIT(8)
85 #define VEND1_GLOBAL_INT_STD_MASK_AN2           BIT(7)
86 #define VEND1_GLOBAL_INT_STD_MASK_GBE           BIT(6)
87 #define VEND1_GLOBAL_INT_STD_MASK_ALL           BIT(0)
88
89 #define VEND1_GLOBAL_INT_VEND_MASK              0xff01
90 #define VEND1_GLOBAL_INT_VEND_MASK_PMA          BIT(15)
91 #define VEND1_GLOBAL_INT_VEND_MASK_PCS          BIT(14)
92 #define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS       BIT(13)
93 #define VEND1_GLOBAL_INT_VEND_MASK_AN           BIT(12)
94 #define VEND1_GLOBAL_INT_VEND_MASK_GBE          BIT(11)
95 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1      BIT(2)
96 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2      BIT(1)
97 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3      BIT(0)
98
99 static int aqr_config_aneg(struct phy_device *phydev)
100 {
101         bool changed = false;
102         u16 reg;
103         int ret;
104
105         if (phydev->autoneg == AUTONEG_DISABLE)
106                 return genphy_c45_pma_setup_forced(phydev);
107
108         ret = genphy_c45_an_config_aneg(phydev);
109         if (ret < 0)
110                 return ret;
111         if (ret > 0)
112                 changed = true;
113
114         /* Clause 45 has no standardized support for 1000BaseT, therefore
115          * use vendor registers for this mode.
116          */
117         reg = 0;
118         if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
119                               phydev->advertising))
120                 reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
121
122         if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
123                               phydev->advertising))
124                 reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
125
126         ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
127                                      MDIO_AN_VEND_PROV_1000BASET_HALF |
128                                      MDIO_AN_VEND_PROV_1000BASET_FULL, reg);
129         if (ret < 0)
130                 return ret;
131         if (ret > 0)
132                 changed = true;
133
134         return genphy_c45_check_and_restart_aneg(phydev, changed);
135 }
136
137 static int aqr_config_intr(struct phy_device *phydev)
138 {
139         bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
140         int err;
141
142         err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,
143                             en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);
144         if (err < 0)
145                 return err;
146
147         err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,
148                             en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);
149         if (err < 0)
150                 return err;
151
152         return phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
153                              en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
154                              VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
155 }
156
157 static int aqr_ack_interrupt(struct phy_device *phydev)
158 {
159         int reg;
160
161         reg = phy_read_mmd(phydev, MDIO_MMD_AN,
162                            MDIO_AN_TX_VEND_INT_STATUS2);
163         return (reg < 0) ? reg : 0;
164 }
165
166 static int aqr_read_status(struct phy_device *phydev)
167 {
168         int val;
169
170         if (phydev->autoneg == AUTONEG_ENABLE) {
171                 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
172                 if (val < 0)
173                         return val;
174
175                 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
176                                  phydev->lp_advertising,
177                                  val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);
178                 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
179                                  phydev->lp_advertising,
180                                  val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);
181         }
182
183         return genphy_c45_read_status(phydev);
184 }
185
186 static int aqr107_read_downshift_event(struct phy_device *phydev)
187 {
188         int val;
189
190         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS1);
191         if (val < 0)
192                 return val;
193
194         return !!(val & MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT);
195 }
196
197 static int aqr107_read_rate(struct phy_device *phydev)
198 {
199         int val;
200
201         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
202         if (val < 0)
203                 return val;
204
205         switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
206         case MDIO_AN_TX_VEND_STATUS1_10BASET:
207                 phydev->speed = SPEED_10;
208                 break;
209         case MDIO_AN_TX_VEND_STATUS1_100BASETX:
210                 phydev->speed = SPEED_100;
211                 break;
212         case MDIO_AN_TX_VEND_STATUS1_1000BASET:
213                 phydev->speed = SPEED_1000;
214                 break;
215         case MDIO_AN_TX_VEND_STATUS1_2500BASET:
216                 phydev->speed = SPEED_2500;
217                 break;
218         case MDIO_AN_TX_VEND_STATUS1_5000BASET:
219                 phydev->speed = SPEED_5000;
220                 break;
221         case MDIO_AN_TX_VEND_STATUS1_10GBASET:
222                 phydev->speed = SPEED_10000;
223                 break;
224         default:
225                 phydev->speed = SPEED_UNKNOWN;
226                 break;
227         }
228
229         if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
230                 phydev->duplex = DUPLEX_FULL;
231         else
232                 phydev->duplex = DUPLEX_HALF;
233
234         return 0;
235 }
236
237 static int aqr107_read_status(struct phy_device *phydev)
238 {
239         int val, ret;
240
241         ret = aqr_read_status(phydev);
242         if (ret)
243                 return ret;
244
245         if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
246                 return 0;
247
248         val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
249         if (val < 0)
250                 return val;
251
252         switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
253         case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
254         case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
255                 phydev->interface = PHY_INTERFACE_MODE_10GKR;
256                 break;
257         case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
258                 phydev->interface = PHY_INTERFACE_MODE_SGMII;
259                 break;
260         case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
261                 phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
262                 break;
263         default:
264                 phydev->interface = PHY_INTERFACE_MODE_NA;
265                 break;
266         }
267
268         val = aqr107_read_downshift_event(phydev);
269         if (val <= 0)
270                 return val;
271
272         phydev_warn(phydev, "Downshift occurred! Cabling may be defective.\n");
273
274         /* Read downshifted rate from vendor register */
275         return aqr107_read_rate(phydev);
276 }
277
278 static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
279 {
280         int val, cnt, enable;
281
282         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);
283         if (val < 0)
284                 return val;
285
286         enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);
287         cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
288
289         *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;
290
291         return 0;
292 }
293
294 static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
295 {
296         int val = 0;
297
298         if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))
299                 return -E2BIG;
300
301         if (cnt != DOWNSHIFT_DEV_DISABLE) {
302                 val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;
303                 val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);
304         }
305
306         return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
307                               MDIO_AN_VEND_PROV_DOWNSHIFT_EN |
308                               MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
309 }
310
311 static int aqr107_get_tunable(struct phy_device *phydev,
312                               struct ethtool_tunable *tuna, void *data)
313 {
314         switch (tuna->id) {
315         case ETHTOOL_PHY_DOWNSHIFT:
316                 return aqr107_get_downshift(phydev, data);
317         default:
318                 return -EOPNOTSUPP;
319         }
320 }
321
322 static int aqr107_set_tunable(struct phy_device *phydev,
323                               struct ethtool_tunable *tuna, const void *data)
324 {
325         switch (tuna->id) {
326         case ETHTOOL_PHY_DOWNSHIFT:
327                 return aqr107_set_downshift(phydev, *(const u8 *)data);
328         default:
329                 return -EOPNOTSUPP;
330         }
331 }
332
333 static int aqr107_config_init(struct phy_device *phydev)
334 {
335         /* Check that the PHY interface type is compatible */
336         if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
337             phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
338             phydev->interface != PHY_INTERFACE_MODE_10GKR)
339                 return -ENODEV;
340
341         /* ensure that a latched downshift event is cleared */
342         aqr107_read_downshift_event(phydev);
343
344         return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
345 }
346
347 static int aqcs109_config_init(struct phy_device *phydev)
348 {
349         int ret;
350
351         /* Check that the PHY interface type is compatible */
352         if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
353             phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
354                 return -ENODEV;
355
356         /* AQCS109 belongs to a chip family partially supporting 10G and 5G.
357          * PMA speed ability bits are the same for all members of the family,
358          * AQCS109 however supports speeds up to 2.5G only.
359          */
360         ret = phy_set_max_speed(phydev, SPEED_2500);
361         if (ret)
362                 return ret;
363
364         /* ensure that a latched downshift event is cleared */
365         aqr107_read_downshift_event(phydev);
366
367         return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
368 }
369
370 static void aqr107_link_change_notify(struct phy_device *phydev)
371 {
372         u8 fw_major, fw_minor;
373         bool downshift, short_reach, afr;
374         int val;
375
376         if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE)
377                 return;
378
379         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
380         /* call failed or link partner is no Aquantia PHY */
381         if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY))
382                 return;
383
384         short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH;
385         downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT;
386
387         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4);
388         if (val < 0)
389                 return;
390
391         fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val);
392         fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val);
393
394         val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3);
395         if (val < 0)
396                 return;
397
398         afr = val & MDIO_AN_RX_VEND_STAT3_AFR;
399
400         phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n",
401                    fw_major, fw_minor,
402                    short_reach ? ", short reach mode" : "",
403                    downshift ? ", fast-retrain downshift advertised" : "",
404                    afr ? ", fast reframe advertised" : "");
405 }
406
407 static struct phy_driver aqr_driver[] = {
408 {
409         PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
410         .name           = "Aquantia AQ1202",
411         .aneg_done      = genphy_c45_aneg_done,
412         .get_features   = genphy_c45_pma_read_abilities,
413         .config_aneg    = aqr_config_aneg,
414         .config_intr    = aqr_config_intr,
415         .ack_interrupt  = aqr_ack_interrupt,
416         .read_status    = aqr_read_status,
417 },
418 {
419         PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),
420         .name           = "Aquantia AQ2104",
421         .aneg_done      = genphy_c45_aneg_done,
422         .get_features   = genphy_c45_pma_read_abilities,
423         .config_aneg    = aqr_config_aneg,
424         .config_intr    = aqr_config_intr,
425         .ack_interrupt  = aqr_ack_interrupt,
426         .read_status    = aqr_read_status,
427 },
428 {
429         PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
430         .name           = "Aquantia AQR105",
431         .aneg_done      = genphy_c45_aneg_done,
432         .get_features   = genphy_c45_pma_read_abilities,
433         .config_aneg    = aqr_config_aneg,
434         .config_intr    = aqr_config_intr,
435         .ack_interrupt  = aqr_ack_interrupt,
436         .read_status    = aqr_read_status,
437 },
438 {
439         PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
440         .name           = "Aquantia AQR106",
441         .aneg_done      = genphy_c45_aneg_done,
442         .get_features   = genphy_c45_pma_read_abilities,
443         .config_aneg    = aqr_config_aneg,
444         .config_intr    = aqr_config_intr,
445         .ack_interrupt  = aqr_ack_interrupt,
446         .read_status    = aqr_read_status,
447 },
448 {
449         PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
450         .name           = "Aquantia AQR107",
451         .aneg_done      = genphy_c45_aneg_done,
452         .get_features   = genphy_c45_pma_read_abilities,
453         .probe          = aqr_hwmon_probe,
454         .config_init    = aqr107_config_init,
455         .config_aneg    = aqr_config_aneg,
456         .config_intr    = aqr_config_intr,
457         .ack_interrupt  = aqr_ack_interrupt,
458         .read_status    = aqr107_read_status,
459         .get_tunable    = aqr107_get_tunable,
460         .set_tunable    = aqr107_set_tunable,
461         .link_change_notify = aqr107_link_change_notify,
462 },
463 {
464         PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
465         .name           = "Aquantia AQCS109",
466         .aneg_done      = genphy_c45_aneg_done,
467         .get_features   = genphy_c45_pma_read_abilities,
468         .probe          = aqr_hwmon_probe,
469         .config_init    = aqcs109_config_init,
470         .config_aneg    = aqr_config_aneg,
471         .config_intr    = aqr_config_intr,
472         .ack_interrupt  = aqr_ack_interrupt,
473         .read_status    = aqr107_read_status,
474         .get_tunable    = aqr107_get_tunable,
475         .set_tunable    = aqr107_set_tunable,
476         .link_change_notify = aqr107_link_change_notify,
477 },
478 {
479         PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
480         .name           = "Aquantia AQR405",
481         .aneg_done      = genphy_c45_aneg_done,
482         .get_features   = genphy_c45_pma_read_abilities,
483         .config_aneg    = aqr_config_aneg,
484         .config_intr    = aqr_config_intr,
485         .ack_interrupt  = aqr_ack_interrupt,
486         .read_status    = aqr_read_status,
487 },
488 };
489
490 module_phy_driver(aqr_driver);
491
492 static struct mdio_device_id __maybe_unused aqr_tbl[] = {
493         { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
494         { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
495         { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
496         { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
497         { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
498         { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
499         { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
500         { }
501 };
502
503 MODULE_DEVICE_TABLE(mdio, aqr_tbl);
504
505 MODULE_DESCRIPTION("Aquantia PHY driver");
506 MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");
507 MODULE_LICENSE("GPL v2");