1 /*
2 * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
3 */
4 
5 #ifndef __MII_H__
6 #define __MII_H__
7 
8 /* Basic mode control register. */
9 #define CVI_BMCR_RESV           (0x003f)
10 #define CVI_BMCR_SPEED1000      (0x0040)
11 #define CVI_BMCR_CTST           (0x0080)
12 #define CVI_BMCR_FULLDPLX       (0x0100)
13 #define CVI_BMCR_ANRESTART      (0x0200)
14 #define CVI_BMCR_ISOLATE        (0x0400)
15 #define CVI_BMCR_PDOWN          (0x0800)
16 #define CVI_BMCR_ANENABLE       (0x1000)
17 #define CVI_BMCR_SPEED100       (0x2000)
18 #define CVI_BMCR_LOOPBACK       (0x4000)
19 #define CVI_BMCR_RESET          (0x8000)
20 
21 /* Basic mode status register. */
22 #define CVI_BMSR_ERCAP          (0x0001)
23 #define CVI_BMSR_JCD            (0x0002)
24 #define CVI_BMSR_LSTATUS        (0x0004)
25 #define CVI_BMSR_ANEGCAPABLE    (0x0008)
26 #define CVI_BMSR_RFAULT         (0x0010)
27 #define CVI_BMSR_ANEGCOMPLETE   (0x0020)
28 #define CVI_BMSR_RESV           (0x00c0)
29 #define CVI_BMSR_ESTATEN        (0x0100)
30 #define CVI_BMSR_100HALF2       (0x0200)
31 #define CVI_BMSR_100FULL2       (0x0400)
32 #define CVI_BMSR_10HALF         (0x0800)
33 #define CVI_BMSR_10FULL         (0x1000)
34 #define CVI_BMSR_100HALF        (0x2000)
35 #define CVI_BMSR_100FULL        (0x4000)
36 #define CVI_BMSR_100BASE4       (0x8000)
37 
38 /* Advertisement control register. */
39 #define CVI_ADVERTISE_CSMA            (0x0001)
40 #define CVI_ADVERTISE_SLCT            (0x001f)
41 #define CVI_ADVERTISE_10HALF          (0x0020)
42 #define CVI_ADVERTISE_1000XFULL       (0x0020)
43 #define CVI_ADVERTISE_10FULL          (0x0040)
44 #define CVI_ADVERTISE_1000XHALF       (0x0040)
45 #define CVI_ADVERTISE_100HALF         (0x0080)
46 #define CVI_ADVERTISE_1000XPAUSE      (0x0080)
47 #define CVI_ADVERTISE_100FULL         (0x0100)
48 #define CVI_ADVERTISE_1000XPSE_ASYM   (0x0100)
49 #define CVI_ADVERTISE_100BASE4        (0x0200)
50 #define CVI_ADVERTISE_PAUSE_CAP       (0x0400)
51 #define CVI_ADVERTISE_PAUSE_ASYM      (0x0800)
52 #define CVI_ADVERTISE_RESV            (0x1000)
53 #define CVI_ADVERTISE_RFAULT          (0x2000)
54 #define CVI_ADVERTISE_LPACK           (0x4000)
55 #define CVI_ADVERTISE_NPAGE           (0x8000)
56 
57 /* Generic MII registers. */
58 
59 #define CVI_MII_BMCR            (0x00)
60 #define CVI_MII_BMSR            (0x01)
61 #define CVI_MII_PHYSID1         (0x02)
62 #define CVI_MII_PHYSID2         (0x03)
63 #define CVI_MII_ADVERTISE       (0x04)
64 #define CVI_MII_LPA             (0x05)
65 #define CVI_MII_EXPANSION       (0x06)
66 #define CVI_MII_CTRL1000        (0x09)
67 #define CVI_MII_STAT1000        (0x0a)
68 #define CVI_MII_ESTATUS         (0x0f)
69 #define CVI_MII_DCOUNTER        (0x12)
70 #define CVI_MII_FCSCOUNTER      (0x13)
71 #define CVI_MII_NWAYTEST        (0x14)
72 #define CVI_MII_RERRCOUNTER     (0x15)
73 #define CVI_MII_SREVISION       (0x16)
74 #define CVI_MII_RESV1           (0x17)
75 #define CVI_MII_LBRERROR        (0x18)
76 #define CVI_MII_PHYADDR         (0x19)
77 #define CVI_MII_RESV2           (0x1a)
78 #define CVI_MII_TPISTATUS       (0x1b)
79 #define CVI_MII_NCONFIG         (0x1c)
80 
81 #define CVI_ADVERTISE_FULL (CVI_ADVERTISE_100FULL | CVI_ADVERTISE_10FULL | \
82             CVI_ADVERTISE_CSMA)
83 #define CVI_ADVERTISE_ALL (CVI_ADVERTISE_10HALF | CVI_ADVERTISE_10FULL | \
84                CVI_ADVERTISE_100HALF | CVI_ADVERTISE_100FULL)
85 
86 /* Expansion register for auto-negotiation. */
87 #define CVI_EXPANSION_NWAY            (0x0001)
88 #define CVI_EXPANSION_LCWP            (0x0002)
89 #define CVI_EXPANSION_ENABLENPAGE     (0x0004)
90 #define CVI_EXPANSION_NPCAPABLE       (0x0008)
91 #define CVI_EXPANSION_MFAULTS         (0x0010)
92 #define CVI_ESTATUS_1000_THALF        (0x1000)
93 #define CVI_ESTATUS_1000_TFULL        (0x2000)
94 #define CVI_ESTATUS_1000_XHALF        (0x4000)
95 #define CVI_ESTATUS_1000_XFULL        (0x8000)
96 #define CVI_EXPANSION_RESV            (0xffe0)
97 
98 /* Link partner ability register. */
99 #define CVI_LPA_SLCT                 (0x001f)
100 #define CVI_LPA_10HALF               (0x0020)
101 #define CVI_LPA_1000XFULL            (0x0020)
102 #define CVI_LPA_10FULL               (0x0040)
103 #define CVI_LPA_1000XHALF            (0x0040)
104 #define CVI_LPA_100HALF              (0x0080)
105 #define CVI_LPA_1000XPAUSE           (0x0080)
106 #define CVI_LPA_100FULL              (0x0100)
107 #define CVI_LPA_1000XPAUSE_ASYM      (0x0100)
108 #define CVI_LPA_100BASE4             (0x0200)
109 #define CVI_LPA_PAUSE_CAP            (0x0400)
110 #define CVI_LPA_PAUSE_ASYM           (0x0800)
111 #define CVI_LPA_RESV                 (0x1000)
112 #define CVI_LPA_RFAULT               (0x2000)
113 #define CVI_LPA_LPACK                (0x4000)
114 #define CVI_LPA_NPAGE                (0x8000)
115 
116 #define CVI_LPA_DUPLEX      (CVI_LPA_10FULL | CVI_LPA_100FULL)
117 #define CVI_LPA_100         (CVI_LPA_100FULL | CVI_LPA_100HALF | CVI_LPA_100BASE4)
118 /* N-way test register. */
119 #define CVI_NWAYTEST_RESV1      (0x00ff)
120 #define CVI_NWAYTEST_LOOPBACK   (0x0100)
121 #define CVI_NWAYTEST_RESV2      (0xfe00)
122 
123 /* 1000BASE-T Control register */
124 #define CVI_ADVERTISE_1000FULL  0x0200
125 #define CVI_ADVERTISE_1000HALF  0x0100
126 
127 /* 1000BASE-T Status register */
128 #define CVI_LPA_1000LOCALRXOK   0x2000
129 #define CVI_LPA_1000REMRXOK     0x1000
130 #define CVI_LPA_1000FULL        0x0800
131 #define CVI_LPA_1000HALF        0x0400
132 
133 /* Flow control flags */
134 #define CVI_FLOW_CTRL_TX        0x01
135 #define CVI_FLOW_CTRL_RX        0x02
136 
137 /**
138  * mii_nway_result
139  * @negotiated: value of MII ANAR and'd with ANLPAR
140  *
141  * Given a set of MII abilities, check each bit and returns the
142  * currently supported media, in the priority order defined by
143  * IEEE 802.3u.  We use LPA_xxx constants but note this is not the
144  * value of LPA solely, as described above.
145  *
146  * The one exception to IEEE 802.3u is that 100baseT4 is placed
147  * between 100T-full and 100T-half.  If your phy does not support
148  * 100T4 this is fine. If your phy places 100T4 elsewhere in the
149  * priority order, you will need to roll your own function.
150  */
mii_nway_result(unsigned int negotiated)151 static inline unsigned int mii_nway_result (unsigned int negotiated)
152 {
153     unsigned int ret;
154 
155     if (negotiated & CVI_LPA_100FULL)
156         ret = CVI_LPA_100FULL;
157     else if (negotiated & CVI_LPA_100BASE4)
158         ret = CVI_LPA_100BASE4;
159     else if (negotiated & CVI_LPA_100HALF)
160         ret = CVI_LPA_100HALF;
161     else if (negotiated & CVI_LPA_10FULL)
162         ret = CVI_LPA_10FULL;
163     else
164         ret = CVI_LPA_10HALF;
165 
166     return ret;
167 }
168 
169 /**
170  * mii_duplex
171  * @duplex_lock: Non-zero if duplex is locked at full
172  * @negotiated: value of MII ANAR and'd with ANLPAR
173  *
174  * A small helper function for a common case.  Returns one
175  * if the media is operating or locked at full duplex, and
176  * returns zero otherwise.
177  */
mii_duplex(unsigned int duplex_lock,unsigned int negotiated)178 static inline unsigned int mii_duplex (unsigned int duplex_lock,
179                        unsigned int negotiated)
180 {
181     if (duplex_lock)
182         return 1;
183     if (mii_nway_result(negotiated) & CVI_LPA_DUPLEX)
184         return 1;
185     return 0;
186 }
187 
188 #endif /* __LINUX_MII_H__ */
189