1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2016,2017 SoftIron Inc.
5 * Copyright (c) 2020 Advanced Micro Devices, Inc.
6 *
7 * This software was developed by Andrew Turner under
8 * the sponsorship of SoftIron Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #ifndef _XGBE_OSDEP_H_
33 #define _XGBE_OSDEP_H_
34
35 #include <sys/endian.h>
36 #include <sys/socket.h>
37
38 #include <net/ethernet.h>
39 #include <net/if.h>
40 #include <net/if_var.h>
41 #include <net/iflib.h>
42
43 MALLOC_DECLARE(M_AXGBE);
44
45 typedef uint16_t __le16;
46 typedef uint16_t __be16;
47 typedef uint32_t __le32;
48
49 #define BIT(pos) (1ul << pos)
50
51 #define cpu_to_be16(x) be16toh(x)
52 #define be16_to_cpu(x) htobe16(x)
53 #define lower_32_bits(x) ((x) & 0xffffffffu)
54 #define upper_32_bits(x) (((x) >> 32) & 0xffffffffu)
55 #define cpu_to_le32(x) le32toh(x)
56 #define le32_to_cpu(x) htole32(x)
57 #define cpu_to_le16(x) htole16(x)
58
59 #define for_each_set_bit(bit, addr, size) \
60 for ((bit) = find_first_bit((addr), (size)); \
61 (bit) < (size); \
62 (bit) = find_next_bit((addr), (size), (bit) + 1))
63
64 typedef struct mtx spinlock_t;
65
66 static inline void
spin_lock_init(spinlock_t * spinlock)67 spin_lock_init(spinlock_t *spinlock)
68 {
69 mtx_init(spinlock, "axgbe_spin", NULL, MTX_SPIN);
70 }
71
72 #define spin_lock_irqsave(spinlock, flags) \
73 do { \
74 (flags) = intr_disable(); \
75 mtx_lock_spin(spinlock); \
76 } while (0)
77
78 #define spin_unlock_irqrestore(spinlock, flags) \
79 do { \
80 mtx_unlock_spin(spinlock); \
81 intr_restore(flags); \
82 } while (0)
83
84 #define ADVERTISED_Pause (1 << 0)
85 #define ADVERTISED_Asym_Pause (1 << 1)
86 #define ADVERTISED_Autoneg (1 << 2)
87 #define ADVERTISED_Backplane (1 << 3)
88 #define ADVERTISED_10000baseKR_Full (1 << 4)
89 #define ADVERTISED_2500baseX_Full (1 << 5)
90 #define ADVERTISED_1000baseKX_Full (1 << 6)
91 #define ADVERTISED_100baseT_Full (1 << 7)
92 #define ADVERTISED_10000baseR_FEC (1 << 8)
93 #define ADVERTISED_10000baseT_Full (1 << 9)
94 #define ADVERTISED_2500baseT_Full (1 << 10)
95 #define ADVERTISED_1000baseT_Full (1 << 11)
96 #define ADVERTISED_TP (1 << 12)
97 #define ADVERTISED_FIBRE (1 << 13)
98 #define ADVERTISED_1000baseX_Full (1 << 14)
99 #define ADVERTISED_10000baseSR_Full (1 << 15)
100 #define ADVERTISED_10000baseLR_Full (1 << 16)
101 #define ADVERTISED_10000baseLRM_Full (1 << 17)
102 #define ADVERTISED_10000baseER_Full (1 << 18)
103 #define ADVERTISED_10000baseCR_Full (1 << 19)
104 #define ADVERTISED_100baseT_Half (1 << 20)
105 #define ADVERTISED_1000baseT_Half (1 << 21)
106
107 #define SUPPORTED_Pause (1 << 0)
108 #define SUPPORTED_Asym_Pause (1 << 1)
109 #define SUPPORTED_Autoneg (1 << 2)
110 #define SUPPORTED_Backplane (1 << 3)
111 #define SUPPORTED_10000baseKR_Full (1 << 4)
112 #define SUPPORTED_2500baseX_Full (1 << 5)
113 #define SUPPORTED_1000baseKX_Full (1 << 6)
114 #define SUPPORTED_100baseT_Full (1 << 7)
115 #define SUPPORTED_10000baseR_FEC (1 << 8)
116 #define SUPPORTED_10000baseT_Full (1 << 9)
117 #define SUPPORTED_2500baseT_Full (1 << 10)
118 #define SUPPORTED_1000baseT_Full (1 << 11)
119 #define SUPPORTED_TP (1 << 12)
120 #define SUPPORTED_FIBRE (1 << 13)
121 #define SUPPORTED_1000baseX_Full (1 << 14)
122 #define SUPPORTED_10000baseSR_Full (1 << 15)
123 #define SUPPORTED_10000baseLR_Full (1 << 16)
124 #define SUPPORTED_10000baseLRM_Full (1 << 17)
125 #define SUPPORTED_10000baseER_Full (1 << 18)
126 #define SUPPORTED_10000baseCR_Full (1 << 19)
127 #define SUPPORTED_100baseT_Half (1 << 20)
128 #define SUPPORTED_1000baseT_Half (1 << 21)
129
130 #define LPA_PAUSE_ASYM 0x0800
131
132 #define AUTONEG_DISABLE 0
133 #define AUTONEG_ENABLE 1
134
135 #define DUPLEX_UNKNOWN 1
136 #define DUPLEX_FULL 2
137 #define DUPLEX_HALF 3
138
139 #define SPEED_UNKNOWN 1
140 #define SPEED_10000 2
141 #define SPEED_2500 3
142 #define SPEED_1000 4
143 #define SPEED_100 5
144 #define SPEED_10 6
145
146 #define BMCR_SPEED100 0x2000
147
148 #define MDIO_MMD_PMAPMD 1
149 #define MDIO_MMD_PCS 3
150 #define MDIO_MMD_AN 7
151 #define MDIO_MMD_VEND1 30 /* Vendor specific 1 */
152 #define MDIO_MMD_VEND2 31 /* Vendor specific 2 */
153
154 #define MDIO_PMA_10GBR_FECABLE 170
155 #define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001
156 #define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002
157 #define MII_ADDR_C45 (1<<30)
158
159 #define MDIO_CTRL1 0x00 /* MII_BMCR */
160 #define MDIO_CTRL1_RESET 0x8000 /* BMCR_RESET */
161 #define MDIO_CTRL1_SPEEDSELEXT 0x2040 /* BMCR_SPEED1000|BMCR_SPEED100*/
162 #define MDIO_CTRL1_SPEEDSEL (MDIO_CTRL1_SPEEDSELEXT | 0x3c)
163 #define MDIO_AN_CTRL1_ENABLE 0x1000 /* BMCR_AUTOEN */
164 #define MDIO_CTRL1_LPOWER 0x0800 /* BMCR_PDOWN */
165 #define MDIO_AN_CTRL1_RESTART 0x0200 /* BMCR_STARTNEG */
166
167 #define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00)
168
169 #define MDIO_STAT1 1 /* MII_BMSR */
170 #define MDIO_STAT1_LSTATUS 0x0004 /* BMSR_LINK */
171
172 #define MDIO_DEVID1 2 /* MII_PHYSID1 */
173 #define MDIO_DEVID2 3 /* MII_PHYSID2 */
174 #define MDIO_SPEED 4
175 #define MDIO_DEVS1 5
176 #define MDIO_DEVS2 6
177 #define MDIO_CTRL2 0x07
178 #define MDIO_PCS_CTRL2_10GBR 0x0000
179 #define MDIO_PCS_CTRL2_10GBX 0x0001
180 #define MDIO_PCS_CTRL2_TYPE 0x0003
181
182 #define MDIO_AN_ADVERTISE 16
183
184 #define MDIO_AN_LPA 19
185
186 #define ETH_ALEN ETHER_ADDR_LEN
187 #define ETH_HLEN ETHER_HDR_LEN
188 #define ETH_FCS_LEN 4
189 #define VLAN_HLEN ETHER_VLAN_ENCAP_LEN
190 #define VLAN_NVID 4096
191 #define VLAN_VID_MASK 0x0FFF
192
193 #define CRC32_POLY_LE 0xedb88320
194
195 #define ARRAY_SIZE(x) nitems(x)
196
197 #define BITS_PER_LONG (sizeof(long) * CHAR_BIT)
198 #define BITS_TO_LONGS(n) howmany((n), BITS_PER_LONG)
199
200 #define BITMAP_LAST_WORD_MASK(n) (~0UL >> (BITS_PER_LONG - (n)))
201
202 #define min_t(t, a, b) MIN((t)(a), (t)(b))
203 #define max_t(t, a, b) MAX((t)(a), (t)(b))
204
205 static inline void
clear_bit(int pos,unsigned long * p)206 clear_bit(int pos, unsigned long *p)
207 {
208
209 atomic_clear_long(p, 1ul << pos);
210 }
211
212 static inline int
test_bit(int pos,unsigned long * p)213 test_bit(int pos, unsigned long *p)
214 {
215 unsigned long val;
216
217 val = *p;
218 return ((val & 1ul << pos) != 0);
219 }
220
221 static inline void
set_bit(int pos,unsigned long * p)222 set_bit(int pos, unsigned long *p)
223 {
224
225 atomic_set_long(p, 1ul << pos);
226 }
227
228 static inline int
__ffsl(long mask)229 __ffsl(long mask)
230 {
231
232 return (ffsl(mask) - 1);
233 }
234
235 static inline int
get_bitmask_order(unsigned int count)236 get_bitmask_order(unsigned int count)
237 {
238 int order;
239
240 order = fls(count);
241 return (order); /* We could be slightly more clever with -1 here... */
242 }
243
244 static inline unsigned long
find_next_bit(const unsigned long * addr,unsigned long size,unsigned long offset)245 find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
246 {
247 long mask;
248 int offs;
249 int bit;
250 int pos;
251
252 if (offset >= size)
253 return (size);
254 pos = offset / BITS_PER_LONG;
255 offs = offset % BITS_PER_LONG;
256 bit = BITS_PER_LONG * pos;
257 addr += pos;
258 if (offs) {
259 mask = (*addr) & ~BITMAP_LAST_WORD_MASK(offs);
260 if (mask)
261 return (bit + __ffsl(mask));
262 if (size - bit <= BITS_PER_LONG)
263 return (size);
264 bit += BITS_PER_LONG;
265 addr++;
266 }
267 for (size -= bit; size >= BITS_PER_LONG;
268 size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) {
269 if (*addr == 0)
270 continue;
271 return (bit + __ffsl(*addr));
272 }
273 if (size) {
274 mask = (*addr) & BITMAP_LAST_WORD_MASK(size);
275 if (mask)
276 bit += __ffsl(mask);
277 else
278 bit += size;
279 }
280 return (bit);
281 }
282
283 static inline unsigned long
find_first_bit(const unsigned long * addr,unsigned long size)284 find_first_bit(const unsigned long *addr, unsigned long size)
285 {
286 long mask;
287 int bit;
288
289 for (bit = 0; size >= BITS_PER_LONG;
290 size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) {
291 if (*addr == 0)
292 continue;
293 return (bit + __ffsl(*addr));
294 }
295 if (size) {
296 mask = (*addr) & BITMAP_LAST_WORD_MASK(size);
297 if (mask)
298 bit += __ffsl(mask);
299 else
300 bit += size;
301 }
302 return (bit);
303 }
304
305 #endif /* _XGBE_OSDEP_H_ */
306