c783143dd7ab301f135e009852ed3f2613627a97
[openwrt/staging/dangole.git] /
1 From bc447c21304c1297f340d3daaf69915ebbc1f882 Mon Sep 17 00:00:00 2001
2 From: Vladimir Oltean <vladimir.oltean@nxp.com>
3 Date: Mon, 30 Sep 2019 19:20:26 +0300
4 Subject: [PATCH] mii: Add helpers for parsing SGMII auto-negotiation
5
6 Typically a MAC PCS auto-configures itself after it receives the
7 negotiated link settings from the PHY, but some MAC devices are more
8 special and need manual manipulation of the SGMII AN result.
9
10 Therefore, add the bit definitions for the SGMII registers 4 and 5
11 (local device ability, link partner ability), as well as a link_mode
12 conversion helper that can be used to feed the AN results into
13 phy_resolve_aneg_linkmode.
14
15 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
16 ---
17 include/linux/mii.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
18 include/uapi/linux/mii.h | 10 ++++++++++
19 2 files changed, 60 insertions(+)
20
21 --- a/include/linux/mii.h
22 +++ b/include/linux/mii.h
23 @@ -373,6 +373,56 @@ static inline u32 mii_lpa_to_ethtool_lpa
24 }
25
26 /**
27 + * mii_lpa_mod_linkmode_adv_sgmii
28 + * @lp_advertising: pointer to destination link mode.
29 + * @lpa: value of the MII_LPA register
30 + *
31 + * A small helper function that translates MII_LPA bits to
32 + * linkmode advertisement settings for SGMII.
33 + * Leaves other bits unchanged.
34 + */
35 +static inline void
36 +mii_lpa_mod_linkmode_lpa_sgmii(unsigned long *lp_advertising, u32 lpa)
37 +{
38 + u32 speed_duplex = lpa & LPA_SGMII_DPX_SPD_MASK;
39 +
40 + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, lp_advertising,
41 + speed_duplex == LPA_SGMII_1000HALF);
42 +
43 + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, lp_advertising,
44 + speed_duplex == LPA_SGMII_1000FULL);
45 +
46 + linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, lp_advertising,
47 + speed_duplex == LPA_SGMII_100HALF);
48 +
49 + linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, lp_advertising,
50 + speed_duplex == LPA_SGMII_100FULL);
51 +
52 + linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, lp_advertising,
53 + speed_duplex == LPA_SGMII_10HALF);
54 +
55 + linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, lp_advertising,
56 + speed_duplex == LPA_SGMII_10FULL);
57 +}
58 +
59 +/**
60 + * mii_lpa_to_linkmode_adv_sgmii
61 + * @advertising: pointer to destination link mode.
62 + * @lpa: value of the MII_LPA register
63 + *
64 + * A small helper function that translates MII_ADVERTISE bits
65 + * to linkmode advertisement settings when in SGMII mode.
66 + * Clears the old value of advertising.
67 + */
68 +static inline void mii_lpa_to_linkmode_lpa_sgmii(unsigned long *lp_advertising,
69 + u32 lpa)
70 +{
71 + linkmode_zero(lp_advertising);
72 +
73 + mii_lpa_mod_linkmode_lpa_sgmii(lp_advertising, lpa);
74 +}
75 +
76 +/**
77 * mii_adv_mod_linkmode_adv_t
78 * @advertising:pointer to destination link mode.
79 * @adv: value of the MII_ADVERTISE register
80 --- a/include/uapi/linux/mii.h
81 +++ b/include/uapi/linux/mii.h
82 @@ -71,6 +71,7 @@
83 /* Advertisement control register. */
84 #define ADVERTISE_SLCT 0x001f /* Selector bits */
85 #define ADVERTISE_CSMA 0x0001 /* Only selector supported */
86 +#define ADVERTISE_SGMII 0x0001 /* Can do SGMII */
87 #define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
88 #define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
89 #define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
90 @@ -94,6 +95,7 @@
91
92 /* Link partner ability register. */
93 #define LPA_SLCT 0x001f /* Same as advertise selector */
94 +#define LPA_SGMII 0x0001 /* Can do SGMII */
95 #define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
96 #define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
97 #define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
98 @@ -104,11 +106,19 @@
99 #define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
100 #define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
101 #define LPA_PAUSE_CAP 0x0400 /* Can pause */
102 +#define LPA_SGMII_DPX_SPD_MASK 0x1C00 /* SGMII duplex and speed bits */
103 +#define LPA_SGMII_10HALF 0x0000 /* Can do SGMII 10mbps half-duplex */
104 +#define LPA_SGMII_10FULL 0x1000 /* Can do SGMII 10mbps full-duplex */
105 +#define LPA_SGMII_100HALF 0x0400 /* Can do SGMII 100mbps half-duplex */
106 +#define LPA_SGMII_100FULL 0x1400 /* Can do SGMII 100mbps full-duplex */
107 #define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
108 +#define LPA_SGMII_1000HALF 0x0800 /* Can do SGMII 1000mbps half-duplex */
109 +#define LPA_SGMII_1000FULL 0x1800 /* Can do SGMII 1000mbps full-duplex */
110 #define LPA_RESV 0x1000 /* Unused... */
111 #define LPA_RFAULT 0x2000 /* Link partner faulted */
112 #define LPA_LPACK 0x4000 /* Link partner acked us */
113 #define LPA_NPAGE 0x8000 /* Next page bit */
114 +#define LPA_SGMII_LINK 0x8000 /* Link partner has link */
115
116 #define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
117 #define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)