sfc: Rework the bitfield header so that we can identify fields by bit number
[linux-2.6] / drivers / net / sfc / gmii.h
1 /****************************************************************************
2  * Driver for Solarflare Solarstorm network controllers and boards
3  * Copyright 2005-2006 Fen Systems Ltd.
4  * Copyright 2006 Solarflare Communications Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published
8  * by the Free Software Foundation, incorporated herein by reference.
9  */
10
11 #ifndef EFX_GMII_H
12 #define EFX_GMII_H
13
14 /*
15  * GMII interface
16  */
17
18 #include <linux/mii.h>
19
20 /* GMII registers, excluding registers already defined as MII
21  * registers in mii.h
22  */
23 #define GMII_IER                0x12    /* Interrupt enable register */
24 #define GMII_ISR                0x13    /* Interrupt status register */
25
26 /* Interrupt enable register */
27 #define IER_ANEG_ERR            0x8000  /* Bit 15 - autonegotiation error */
28 #define IER_SPEED_CHG           0x4000  /* Bit 14 - speed changed */
29 #define IER_DUPLEX_CHG          0x2000  /* Bit 13 - duplex changed */
30 #define IER_PAGE_RCVD           0x1000  /* Bit 12 - page received */
31 #define IER_ANEG_DONE           0x0800  /* Bit 11 - autonegotiation complete */
32 #define IER_LINK_CHG            0x0400  /* Bit 10 - link status changed */
33 #define IER_SYM_ERR             0x0200  /* Bit 9 - symbol error */
34 #define IER_FALSE_CARRIER       0x0100  /* Bit 8 - false carrier */
35 #define IER_FIFO_ERR            0x0080  /* Bit 7 - FIFO over/underflow */
36 #define IER_MDIX_CHG            0x0040  /* Bit 6 - MDI crossover changed */
37 #define IER_DOWNSHIFT           0x0020  /* Bit 5 - downshift */
38 #define IER_ENERGY              0x0010  /* Bit 4 - energy detect */
39 #define IER_DTE_POWER           0x0004  /* Bit 2 - DTE power detect */
40 #define IER_POLARITY_CHG        0x0002  /* Bit 1 - polarity changed */
41 #define IER_JABBER              0x0001  /* Bit 0 - jabber */
42
43 /* Interrupt status register */
44 #define ISR_ANEG_ERR            0x8000  /* Bit 15 - autonegotiation error */
45 #define ISR_SPEED_CHG           0x4000  /* Bit 14 - speed changed */
46 #define ISR_DUPLEX_CHG          0x2000  /* Bit 13 - duplex changed */
47 #define ISR_PAGE_RCVD           0x1000  /* Bit 12 - page received */
48 #define ISR_ANEG_DONE           0x0800  /* Bit 11 - autonegotiation complete */
49 #define ISR_LINK_CHG            0x0400  /* Bit 10 - link status changed */
50 #define ISR_SYM_ERR             0x0200  /* Bit 9 - symbol error */
51 #define ISR_FALSE_CARRIER       0x0100  /* Bit 8 - false carrier */
52 #define ISR_FIFO_ERR            0x0080  /* Bit 7 - FIFO over/underflow */
53 #define ISR_MDIX_CHG            0x0040  /* Bit 6 - MDI crossover changed */
54 #define ISR_DOWNSHIFT           0x0020  /* Bit 5 - downshift */
55 #define ISR_ENERGY              0x0010  /* Bit 4 - energy detect */
56 #define ISR_DTE_POWER           0x0004  /* Bit 2 - DTE power detect */
57 #define ISR_POLARITY_CHG        0x0002  /* Bit 1 - polarity changed */
58 #define ISR_JABBER              0x0001  /* Bit 0 - jabber */
59
60 /* Logically extended advertisement register */
61 #define GM_ADVERTISE_SLCT               ADVERTISE_SLCT
62 #define GM_ADVERTISE_CSMA               ADVERTISE_CSMA
63 #define GM_ADVERTISE_10HALF             ADVERTISE_10HALF
64 #define GM_ADVERTISE_1000XFULL          ADVERTISE_1000XFULL
65 #define GM_ADVERTISE_10FULL             ADVERTISE_10FULL
66 #define GM_ADVERTISE_1000XHALF          ADVERTISE_1000XHALF
67 #define GM_ADVERTISE_100HALF            ADVERTISE_100HALF
68 #define GM_ADVERTISE_1000XPAUSE         ADVERTISE_1000XPAUSE
69 #define GM_ADVERTISE_100FULL            ADVERTISE_100FULL
70 #define GM_ADVERTISE_1000XPSE_ASYM      ADVERTISE_1000XPSE_ASYM
71 #define GM_ADVERTISE_100BASE4           ADVERTISE_100BASE4
72 #define GM_ADVERTISE_PAUSE_CAP          ADVERTISE_PAUSE_CAP
73 #define GM_ADVERTISE_PAUSE_ASYM         ADVERTISE_PAUSE_ASYM
74 #define GM_ADVERTISE_RESV               ADVERTISE_RESV
75 #define GM_ADVERTISE_RFAULT             ADVERTISE_RFAULT
76 #define GM_ADVERTISE_LPACK              ADVERTISE_LPACK
77 #define GM_ADVERTISE_NPAGE              ADVERTISE_NPAGE
78 #define GM_ADVERTISE_1000FULL           (ADVERTISE_1000FULL << 8)
79 #define GM_ADVERTISE_1000HALF           (ADVERTISE_1000HALF << 8)
80 #define GM_ADVERTISE_1000               (GM_ADVERTISE_1000FULL | \
81                                          GM_ADVERTISE_1000HALF)
82 #define GM_ADVERTISE_FULL               (GM_ADVERTISE_1000FULL | \
83                                          ADVERTISE_FULL)
84 #define GM_ADVERTISE_ALL                (GM_ADVERTISE_1000FULL | \
85                                          GM_ADVERTISE_1000HALF | \
86                                          ADVERTISE_ALL)
87
88 /* Logically extended link partner ability register */
89 #define GM_LPA_SLCT                     LPA_SLCT
90 #define GM_LPA_10HALF                   LPA_10HALF
91 #define GM_LPA_1000XFULL                LPA_1000XFULL
92 #define GM_LPA_10FULL                   LPA_10FULL
93 #define GM_LPA_1000XHALF                LPA_1000XHALF
94 #define GM_LPA_100HALF                  LPA_100HALF
95 #define GM_LPA_1000XPAUSE               LPA_1000XPAUSE
96 #define GM_LPA_100FULL                  LPA_100FULL
97 #define GM_LPA_1000XPAUSE_ASYM          LPA_1000XPAUSE_ASYM
98 #define GM_LPA_100BASE4                 LPA_100BASE4
99 #define GM_LPA_PAUSE_CAP                LPA_PAUSE_CAP
100 #define GM_LPA_PAUSE_ASYM               LPA_PAUSE_ASYM
101 #define GM_LPA_RESV                     LPA_RESV
102 #define GM_LPA_RFAULT                   LPA_RFAULT
103 #define GM_LPA_LPACK                    LPA_LPACK
104 #define GM_LPA_NPAGE                    LPA_NPAGE
105 #define GM_LPA_1000FULL                 (LPA_1000FULL << 6)
106 #define GM_LPA_1000HALF                 (LPA_1000HALF << 6)
107 #define GM_LPA_10000FULL                0x00040000
108 #define GM_LPA_10000HALF                0x00080000
109 #define GM_LPA_DUPLEX                   (GM_LPA_1000FULL | GM_LPA_10000FULL \
110                                          | LPA_DUPLEX)
111 #define GM_LPA_10                       (LPA_10FULL | LPA_10HALF)
112 #define GM_LPA_100                      LPA_100
113 #define GM_LPA_1000                     (GM_LPA_1000FULL | GM_LPA_1000HALF)
114 #define GM_LPA_10000                    (GM_LPA_10000FULL | GM_LPA_10000HALF)
115
116 /* Retrieve GMII autonegotiation advertised abilities
117  *
118  * The MII advertisment register (MII_ADVERTISE) is logically extended
119  * to include advertisement bits ADVERTISE_1000FULL and
120  * ADVERTISE_1000HALF from MII_CTRL1000.  The result can be tested
121  * against the GM_ADVERTISE_xxx constants.
122  */
123 static inline unsigned int gmii_advertised(struct mii_if_info *gmii)
124 {
125         unsigned int advertise;
126         unsigned int ctrl1000;
127
128         advertise = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_ADVERTISE);
129         ctrl1000 = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_CTRL1000);
130         return (((ctrl1000 << 8) & GM_ADVERTISE_1000) | advertise);
131 }
132
133 /* Retrieve GMII autonegotiation link partner abilities
134  *
135  * The MII link partner ability register (MII_LPA) is logically
136  * extended by adding bits LPA_1000HALF and LPA_1000FULL from
137  * MII_STAT1000.  The result can be tested against the GM_LPA_xxx
138  * constants.
139  */
140 static inline unsigned int gmii_lpa(struct mii_if_info *gmii)
141 {
142         unsigned int lpa;
143         unsigned int stat1000;
144
145         lpa = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_LPA);
146         stat1000 = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_STAT1000);
147         return (((stat1000 << 6) & GM_LPA_1000) | lpa);
148 }
149
150 /* Calculate GMII autonegotiated link technology
151  *
152  * "negotiated" should be the result of gmii_advertised() logically
153  * ANDed with the result of gmii_lpa().
154  *
155  * "tech" will be negotiated with the unused bits masked out.  For
156  * example, if both ends of the link are capable of both
157  * GM_LPA_1000FULL and GM_LPA_100FULL, GM_LPA_100FULL will be masked
158  * out.
159  */
160 static inline unsigned int gmii_nway_result(unsigned int negotiated)
161 {
162         unsigned int other_bits;
163
164         /* Mask out the speed and duplexity bits */
165         other_bits = negotiated & ~(GM_LPA_10 | GM_LPA_100 | GM_LPA_1000);
166
167         if (negotiated & GM_LPA_1000FULL)
168                 return (other_bits | GM_LPA_1000FULL);
169         else if (negotiated & GM_LPA_1000HALF)
170                 return (other_bits | GM_LPA_1000HALF);
171         else
172                 return (other_bits | mii_nway_result(negotiated));
173 }
174
175 /* Calculate GMII non-autonegotiated link technology
176  *
177  * This provides an equivalent to gmii_nway_result for the case when
178  * autonegotiation is disabled.
179  */
180 static inline unsigned int gmii_forced_result(unsigned int bmcr)
181 {
182         unsigned int result;
183         int full_duplex;
184
185         full_duplex = bmcr & BMCR_FULLDPLX;
186         if (bmcr & BMCR_SPEED1000)
187                 result = full_duplex ? GM_LPA_1000FULL : GM_LPA_1000HALF;
188         else if (bmcr & BMCR_SPEED100)
189                 result = full_duplex ? GM_LPA_100FULL : GM_LPA_100HALF;
190         else
191                 result = full_duplex ? GM_LPA_10FULL : GM_LPA_10HALF;
192         return result;
193 }
194
195 #endif /* EFX_GMII_H */