File: | dev/pci/if_msk.c |
Warning: | line 1974, column 3 Access to field 'sk_softc' results in a dereference of a null pointer (loaded from variable 'sc_if0') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: if_msk.c,v 1.143 2023/11/10 15:51:20 bluhm Exp $ */ | |||
2 | ||||
3 | /* | |||
4 | * Copyright (c) 1997, 1998, 1999, 2000 | |||
5 | * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. | |||
6 | * | |||
7 | * Redistribution and use in source and binary forms, with or without | |||
8 | * modification, are permitted provided that the following conditions | |||
9 | * are met: | |||
10 | * 1. Redistributions of source code must retain the above copyright | |||
11 | * notice, this list of conditions and the following disclaimer. | |||
12 | * 2. Redistributions in binary form must reproduce the above copyright | |||
13 | * notice, this list of conditions and the following disclaimer in the | |||
14 | * documentation and/or other materials provided with the distribution. | |||
15 | * 3. All advertising materials mentioning features or use of this software | |||
16 | * must display the following acknowledgement: | |||
17 | * This product includes software developed by Bill Paul. | |||
18 | * 4. Neither the name of the author nor the names of any co-contributors | |||
19 | * may be used to endorse or promote products derived from this software | |||
20 | * without specific prior written permission. | |||
21 | * | |||
22 | * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND | |||
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD | |||
26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |||
32 | * THE POSSIBILITY OF SUCH DAMAGE. | |||
33 | * | |||
34 | * $FreeBSD: /c/ncvs/src/sys/pci/if_sk.c,v 1.20 2000/04/22 02:16:37 wpaul Exp $ | |||
35 | */ | |||
36 | ||||
37 | /* | |||
38 | * Copyright (c) 2003 Nathan L. Binkert <binkertn@umich.edu> | |||
39 | * | |||
40 | * Permission to use, copy, modify, and distribute this software for any | |||
41 | * purpose with or without fee is hereby granted, provided that the above | |||
42 | * copyright notice and this permission notice appear in all copies. | |||
43 | * | |||
44 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
45 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
46 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
47 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
48 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||
49 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||
50 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
51 | */ | |||
52 | ||||
53 | /* | |||
54 | * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports | |||
55 | * the SK-984x series adapters, both single port and dual port. | |||
56 | * References: | |||
57 | * The XaQti XMAC II datasheet, | |||
58 | * http://www.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf | |||
59 | * The SysKonnect GEnesis manual, http://www.syskonnect.com | |||
60 | * | |||
61 | * Note: XaQti has been acquired by Vitesse, and Vitesse does not have the | |||
62 | * XMAC II datasheet online. I have put my copy at people.freebsd.org as a | |||
63 | * convenience to others until Vitesse corrects this problem: | |||
64 | * | |||
65 | * http://people.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf | |||
66 | * | |||
67 | * Written by Bill Paul <wpaul@ee.columbia.edu> | |||
68 | * Department of Electrical Engineering | |||
69 | * Columbia University, New York City | |||
70 | */ | |||
71 | ||||
72 | /* | |||
73 | * The SysKonnect gigabit ethernet adapters consist of two main | |||
74 | * components: the SysKonnect GEnesis controller chip and the XaQti Corp. | |||
75 | * XMAC II gigabit ethernet MAC. The XMAC provides all of the MAC | |||
76 | * components and a PHY while the GEnesis controller provides a PCI | |||
77 | * interface with DMA support. Each card may have between 512K and | |||
78 | * 2MB of SRAM on board depending on the configuration. | |||
79 | * | |||
80 | * The SysKonnect GEnesis controller can have either one or two XMAC | |||
81 | * chips connected to it, allowing single or dual port NIC configurations. | |||
82 | * SysKonnect has the distinction of being the only vendor on the market | |||
83 | * with a dual port gigabit ethernet NIC. The GEnesis provides dual FIFOs, | |||
84 | * dual DMA queues, packet/MAC/transmit arbiters and direct access to the | |||
85 | * XMAC registers. This driver takes advantage of these features to allow | |||
86 | * both XMACs to operate as independent interfaces. | |||
87 | */ | |||
88 | ||||
89 | #include "bpfilter.h" | |||
90 | #include "kstat.h" | |||
91 | ||||
92 | #include <sys/param.h> | |||
93 | #include <sys/systm.h> | |||
94 | #include <sys/sockio.h> | |||
95 | #include <sys/mbuf.h> | |||
96 | #include <sys/malloc.h> | |||
97 | #include <sys/kernel.h> | |||
98 | #include <sys/socket.h> | |||
99 | #include <sys/timeout.h> | |||
100 | #include <sys/device.h> | |||
101 | #include <sys/queue.h> | |||
102 | ||||
103 | #include <net/if.h> | |||
104 | ||||
105 | #include <netinet/in.h> | |||
106 | #include <netinet/if_ether.h> | |||
107 | ||||
108 | #include <net/if_media.h> | |||
109 | ||||
110 | #if NBPFILTER1 > 0 | |||
111 | #include <net/bpf.h> | |||
112 | #endif | |||
113 | ||||
114 | #if NKSTAT1 > 0 | |||
115 | #include <sys/kstat.h> | |||
116 | #endif | |||
117 | ||||
118 | #include <dev/mii/mii.h> | |||
119 | #include <dev/mii/miivar.h> | |||
120 | ||||
121 | #include <dev/pci/pcireg.h> | |||
122 | #include <dev/pci/pcivar.h> | |||
123 | #include <dev/pci/pcidevs.h> | |||
124 | ||||
125 | #include <dev/pci/if_skreg.h> | |||
126 | #include <dev/pci/if_mskvar.h> | |||
127 | ||||
128 | #define MSK_STATUS_OWN_SHIFT63 63 | |||
129 | #define MSK_STATUS_OWN_MASK0x1 0x1 | |||
130 | #define MSK_STATUS_OPCODE_SHIFT56 56 | |||
131 | #define MSK_STATUS_OPCODE_MASK0x7f 0x7f | |||
132 | ||||
133 | #define MSK_STATUS_OWN(_d)(((_d) >> 63) & 0x1) \ | |||
134 | (((_d) >> MSK_STATUS_OWN_SHIFT63) & MSK_STATUS_OWN_MASK0x1) | |||
135 | #define MSK_STATUS_OPCODE(_d)(((_d) >> 56) & 0x7f) \ | |||
136 | (((_d) >> MSK_STATUS_OPCODE_SHIFT56) & MSK_STATUS_OPCODE_MASK0x7f) | |||
137 | ||||
138 | #define MSK_STATUS_OPCODE_RXSTAT0x60 0x60 | |||
139 | #define MSK_STATUS_OPCODE_RXTIMESTAMP0x61 0x61 | |||
140 | #define MSK_STATUS_OPCODE_RXVLAN0x62 0x62 | |||
141 | #define MSK_STATUS_OPCODE_RXCKSUM0x64 0x64 | |||
142 | #define MSK_STATUS_OPCODE_RXCKSUMVLAN(0x62 | 0x64) \ | |||
143 | (MSK_STATUS_OPCODE_RXVLAN0x62 | MSK_STATUS_OPCODE_RXCKSUM0x64) | |||
144 | #define MSK_STATUS_OPCODE_RXTIMEVLAN(0x62 | 0x61) \ | |||
145 | (MSK_STATUS_OPCODE_RXVLAN0x62 | MSK_STATUS_OPCODE_RXTIMESTAMP0x61) | |||
146 | #define MSK_STATUS_OPCODE_RSS_HASH0x65 0x65 | |||
147 | #define MSK_STATUS_OPCODE_TXIDX0x68 0x68 | |||
148 | #define MSK_STATUS_OPCODE_MACSEC0x6c 0x6c | |||
149 | #define MSK_STATUS_OPCODE_PUTIDX0x70 0x70 | |||
150 | ||||
151 | #define MSK_STATUS_RXSTAT_PORT_SHIFT48 48 | |||
152 | #define MSK_STATUS_RXSTAT_PORT_MASK0x1 0x1 | |||
153 | #define MSK_STATUS_RXSTAT_LEN_SHIFT32 32 | |||
154 | #define MSK_STATUS_RXSTAT_LEN_MASK0xffff 0xffff | |||
155 | #define MSK_STATUS_RXSTAT_STATUS_SHIFT0 0 | |||
156 | #define MSK_STATUS_RXSTAT_STATUS_MASK0xffffffff 0xffffffff | |||
157 | ||||
158 | #define MSK_STATUS_RXSTAT_PORT(_d)(((_d) >> 48) & 0x1) \ | |||
159 | (((_d) >> MSK_STATUS_RXSTAT_PORT_SHIFT48) & MSK_STATUS_RXSTAT_PORT_MASK0x1) | |||
160 | #define MSK_STATUS_RXSTAT_LEN(_d)(((_d) >> 32) & 0xffff) \ | |||
161 | (((_d) >> MSK_STATUS_RXSTAT_LEN_SHIFT32) & MSK_STATUS_RXSTAT_LEN_MASK0xffff) | |||
162 | #define MSK_STATUS_RXSTAT_STATUS(_d)(((_d) >> 0) & 0xffffffff) \ | |||
163 | (((_d) >> MSK_STATUS_RXSTAT_STATUS_SHIFT0) & MSK_STATUS_RXSTAT_STATUS_MASK0xffffffff) | |||
164 | ||||
165 | #define MSK_STATUS_TXIDX_PORTA_SHIFT0 0 | |||
166 | #define MSK_STATUS_TXIDX_PORTA_MASK0xfff 0xfff | |||
167 | #define MSK_STATUS_TXIDX_PORTB_SHIFT24 24 | |||
168 | #define MSK_STATUS_TXIDX_PORTB_MASK0xfff 0xfff | |||
169 | ||||
170 | #define MSK_STATUS_TXIDX_PORTA(_d)(((_d) >> 0) & 0xfff) \ | |||
171 | (((_d) >> MSK_STATUS_TXIDX_PORTA_SHIFT0) & MSK_STATUS_TXIDX_PORTA_MASK0xfff) | |||
172 | #define MSK_STATUS_TXIDX_PORTB(_d)(((_d) >> 24) & 0xfff) \ | |||
173 | (((_d) >> MSK_STATUS_TXIDX_PORTB_SHIFT24) & MSK_STATUS_TXIDX_PORTB_MASK0xfff) | |||
174 | ||||
175 | int mskc_probe(struct device *, void *, void *); | |||
176 | void mskc_attach(struct device *, struct device *self, void *aux); | |||
177 | int mskc_detach(struct device *, int); | |||
178 | int mskc_activate(struct device *, int); | |||
179 | void mskc_reset(struct sk_softc *); | |||
180 | int msk_probe(struct device *, void *, void *); | |||
181 | void msk_attach(struct device *, struct device *self, void *aux); | |||
182 | int msk_detach(struct device *, int); | |||
183 | int msk_activate(struct device *, int); | |||
184 | void msk_reset(struct sk_if_softc *); | |||
185 | int mskcprint(void *, const char *); | |||
186 | int msk_intr(void *); | |||
187 | void msk_intr_yukon(struct sk_if_softc *); | |||
188 | static inline int msk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t); | |||
189 | void msk_rxeof(struct sk_if_softc *, struct mbuf_list *, uint16_t, uint32_t); | |||
190 | void msk_txeof(struct sk_if_softc *, unsigned int); | |||
191 | static unsigned int msk_encap(struct sk_if_softc *, struct mbuf *, uint32_t); | |||
192 | void msk_start(struct ifnet *); | |||
193 | int msk_ioctl(struct ifnet *, u_long, caddr_t); | |||
194 | void msk_init(void *); | |||
195 | void msk_init_yukon(struct sk_if_softc *); | |||
196 | void msk_stop(struct sk_if_softc *, int); | |||
197 | void msk_watchdog(struct ifnet *); | |||
198 | int msk_ifmedia_upd(struct ifnet *); | |||
199 | void msk_ifmedia_sts(struct ifnet *, struct ifmediareq *); | |||
200 | static int msk_newbuf(struct sk_if_softc *); | |||
201 | int msk_init_rx_ring(struct sk_if_softc *); | |||
202 | int msk_init_tx_ring(struct sk_if_softc *); | |||
203 | void msk_fill_rx_ring(struct sk_if_softc *); | |||
204 | ||||
205 | int msk_miibus_readreg(struct device *, int, int); | |||
206 | void msk_miibus_writereg(struct device *, int, int, int); | |||
207 | void msk_miibus_statchg(struct device *); | |||
208 | ||||
209 | void msk_iff(struct sk_if_softc *); | |||
210 | void msk_tick(void *); | |||
211 | void msk_fill_rx_tick(void *); | |||
212 | ||||
213 | #ifdef MSK_DEBUG | |||
214 | #define DPRINTF(x) if (mskdebug) printf x | |||
215 | #define DPRINTFN(n,x) if (mskdebug >= (n)) printf x | |||
216 | int mskdebug = 0; | |||
217 | ||||
218 | void msk_dump_txdesc(struct msk_tx_desc *, int); | |||
219 | void msk_dump_mbuf(struct mbuf *); | |||
220 | void msk_dump_bytes(const char *, int); | |||
221 | #else | |||
222 | #define DPRINTF(x) | |||
223 | #define DPRINTFN(n,x) | |||
224 | #endif | |||
225 | ||||
226 | #if NKSTAT1 > 0 | |||
227 | struct msk_mib { | |||
228 | const char *name; | |||
229 | uint32_t reg; | |||
230 | enum kstat_kv_type type; | |||
231 | enum kstat_kv_unit unit; | |||
232 | }; | |||
233 | ||||
234 | #define C32 KSTAT_KV_T_COUNTER32 | |||
235 | #define C64 KSTAT_KV_T_COUNTER64 | |||
236 | ||||
237 | #define PKTS KSTAT_KV_U_PACKETS | |||
238 | #define BYTES KSTAT_KV_U_BYTES | |||
239 | #define NONE KSTAT_KV_U_NONE | |||
240 | ||||
241 | static const struct msk_mib msk_mib[] = { | |||
242 | { "InUnicasts", 0x100, C32, PKTS }, | |||
243 | { "InBroadcasts", 0x108, C32, PKTS }, | |||
244 | { "InPause", 0x110, C32, PKTS }, | |||
245 | { "InMulticasts", 0x118, C32, PKTS }, | |||
246 | { "InFCSErr", 0x120, C32, PKTS }, | |||
247 | { "InGoodOctets", 0x130, C64, BYTES }, | |||
248 | { "InBadOctets", 0x140, C64, BYTES }, | |||
249 | { "Undersize", 0x150, C32, PKTS }, | |||
250 | { "Fragments", 0x158, C32, PKTS }, | |||
251 | { "In64Octets", 0x160, C32, PKTS }, | |||
252 | { "In127Octets", 0x168, C32, PKTS }, | |||
253 | { "In255Octets", 0x170, C32, PKTS }, | |||
254 | { "In511Octets", 0x178, C32, PKTS }, | |||
255 | { "In1023Octets", 0x180, C32, PKTS }, | |||
256 | { "In1518Octets", 0x188, C32, PKTS }, | |||
257 | { "InMaxOctets", 0x190, C32, PKTS }, | |||
258 | { "OverSize", 0x198, C32, PKTS }, | |||
259 | { "Jabber", 0x1a8, C32, PKTS }, | |||
260 | { "Overflow", 0x1b0, C32, PKTS }, | |||
261 | ||||
262 | { "OutUnicasts", 0x1c0, C32, PKTS }, | |||
263 | { "OutBroadcasts", 0x1c8, C32, PKTS }, | |||
264 | { "OutPause", 0x1d0, C32, PKTS }, | |||
265 | { "OutMulticasts", 0x1d8, C32, PKTS }, | |||
266 | { "OutOctets", 0x1e0, C64, BYTES }, | |||
267 | { "Out64Octets", 0x1f0, C32, PKTS }, | |||
268 | { "Out127Octets", 0x1f8, C32, PKTS }, | |||
269 | { "Out255Octets", 0x200, C32, PKTS }, | |||
270 | { "Out511Octets", 0x208, C32, PKTS }, | |||
271 | { "Out1023Octets", 0x210, C32, PKTS }, | |||
272 | { "Out1518Octets", 0x218, C32, PKTS }, | |||
273 | { "OutMaxOctets", 0x220, C32, PKTS }, | |||
274 | { "Collisions", 0x230, C32, NONE }, | |||
275 | { "Late", 0x238, C32, NONE }, | |||
276 | { "Excessive", 0x240, C32, PKTS }, | |||
277 | { "Multiple", 0x248, C32, PKTS }, | |||
278 | { "Single", 0x250, C32, PKTS }, | |||
279 | { "Underflow", 0x258, C32, PKTS }, | |||
280 | }; | |||
281 | ||||
282 | #undef C32 | |||
283 | #undef C64 | |||
284 | ||||
285 | #undef PKTS | |||
286 | #undef BYTES | |||
287 | #undef NONE | |||
288 | ||||
289 | struct msk_kstat { | |||
290 | struct rwlock lock; | |||
291 | struct kstat *ks; | |||
292 | }; | |||
293 | ||||
294 | static uint32_t msk_mib_read32(struct sk_if_softc *, uint32_t); | |||
295 | static uint64_t msk_mib_read64(struct sk_if_softc *, uint32_t); | |||
296 | ||||
297 | void msk_kstat_attach(struct sk_if_softc *); | |||
298 | void msk_kstat_detach(struct sk_if_softc *); | |||
299 | int msk_kstat_read(struct kstat *ks); | |||
300 | #endif | |||
301 | ||||
302 | /* supported device vendors */ | |||
303 | const struct pci_matchid mskc_devices[] = { | |||
304 | { PCI_VENDOR_DLINK0x1186, PCI_PRODUCT_DLINK_DGE550SX0x4001 }, | |||
305 | { PCI_VENDOR_DLINK0x1186, PCI_PRODUCT_DLINK_DGE550T_B10x4b03 }, | |||
306 | { PCI_VENDOR_DLINK0x1186, PCI_PRODUCT_DLINK_DGE560SX0x4b02 }, | |||
307 | { PCI_VENDOR_DLINK0x1186, PCI_PRODUCT_DLINK_DGE560T0x4b00 }, | |||
308 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8021CU0x4340 }, | |||
309 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8021X0x4344 }, | |||
310 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8022CU0x4341 }, | |||
311 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8022X0x4345 }, | |||
312 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80350x4350 }, | |||
313 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80360x4351 }, | |||
314 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80380x4352 }, | |||
315 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80390x4353 }, | |||
316 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80400x4354 }, | |||
317 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8040T0x4355 }, | |||
318 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80420x4357 }, | |||
319 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80480x435a }, | |||
320 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80500x4361 }, | |||
321 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80520x4360 }, | |||
322 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80530x4362 }, | |||
323 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80550x4363 }, | |||
324 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8055_20x436d }, | |||
325 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80560x4364 }, | |||
326 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80570x4380 }, | |||
327 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80580x436a }, | |||
328 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80590x4381 }, | |||
329 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8061CU0x4342 }, | |||
330 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8061X0x4346 }, | |||
331 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8062CU0x4343 }, | |||
332 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_8062X0x4347 }, | |||
333 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80700x4365 }, | |||
334 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80710x436b }, | |||
335 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80720x436c }, | |||
336 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80750x4370 }, | |||
337 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_80790x4382 }, | |||
338 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_C0320x4367 }, | |||
339 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_C0330x4356 }, | |||
340 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_C0340x4368 }, | |||
341 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_C0360x4366 }, | |||
342 | { PCI_VENDOR_MARVELL0x11ab, PCI_PRODUCT_MARVELL_YUKON_C0420x4369 }, | |||
343 | { PCI_VENDOR_SCHNEIDERKOCH0x1148, PCI_PRODUCT_SCHNEIDERKOCH_SK9EXX0x9e00 }, | |||
344 | { PCI_VENDOR_SCHNEIDERKOCH0x1148, PCI_PRODUCT_SCHNEIDERKOCH_SK9SXX0x9000 } | |||
345 | }; | |||
346 | ||||
347 | static inline u_int32_t | |||
348 | sk_win_read_4(struct sk_softc *sc, u_int32_t reg) | |||
349 | { | |||
350 | return CSR_READ_4(sc, reg)(((sc)->sk_btag)->read_4(((sc)->sk_bhandle), ((reg)) )); | |||
351 | } | |||
352 | ||||
353 | static inline u_int16_t | |||
354 | sk_win_read_2(struct sk_softc *sc, u_int32_t reg) | |||
355 | { | |||
356 | return CSR_READ_2(sc, reg)(((sc)->sk_btag)->read_2(((sc)->sk_bhandle), ((reg)) )); | |||
357 | } | |||
358 | ||||
359 | static inline u_int8_t | |||
360 | sk_win_read_1(struct sk_softc *sc, u_int32_t reg) | |||
361 | { | |||
362 | return CSR_READ_1(sc, reg)(((sc)->sk_btag)->read_1(((sc)->sk_bhandle), ((reg)) )); | |||
363 | } | |||
364 | ||||
365 | static inline void | |||
366 | sk_win_write_4(struct sk_softc *sc, u_int32_t reg, u_int32_t x) | |||
367 | { | |||
368 | CSR_WRITE_4(sc, reg, x)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((reg) ), ((x)))); | |||
369 | } | |||
370 | ||||
371 | static inline void | |||
372 | sk_win_write_2(struct sk_softc *sc, u_int32_t reg, u_int16_t x) | |||
373 | { | |||
374 | CSR_WRITE_2(sc, reg, x)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((reg) ), ((x)))); | |||
375 | } | |||
376 | ||||
377 | static inline void | |||
378 | sk_win_write_1(struct sk_softc *sc, u_int32_t reg, u_int8_t x) | |||
379 | { | |||
380 | CSR_WRITE_1(sc, reg, x)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((reg) ), ((x)))); | |||
381 | } | |||
382 | ||||
383 | int | |||
384 | msk_miibus_readreg(struct device *dev, int phy, int reg) | |||
385 | { | |||
386 | struct sk_if_softc *sc_if = (struct sk_if_softc *)dev; | |||
387 | u_int16_t val; | |||
388 | int i; | |||
389 | ||||
390 | SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |sk_win_write_2((sc_if)->sk_softc, (((0x0080)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((((phy) & 0x1f) << 11) | (((reg) & 0x1f) << 6) | 0x0020 )) | |||
391 | YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ)sk_win_write_2((sc_if)->sk_softc, (((0x0080)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((((phy) & 0x1f) << 11) | (((reg) & 0x1f) << 6) | 0x0020 )); | |||
392 | ||||
393 | for (i = 0; i < SK_TIMEOUT1000; i++) { | |||
394 | DELAY(1)(*delay_func)(1); | |||
395 | val = SK_YU_READ_2(sc_if, YUKON_SMICR)sk_win_read_2((sc_if)->sk_softc, (((0x0080)) + 0x2800 + (( ((sc_if))->sk_port) * (0x3800 - 0x2800)))); | |||
396 | if (val & YU_SMICR_READ_VALID0x0010) | |||
397 | break; | |||
398 | } | |||
399 | ||||
400 | if (i == SK_TIMEOUT1000) { | |||
401 | printf("%s: phy failed to come ready\n", | |||
402 | sc_if->sk_dev.dv_xname); | |||
403 | return (0); | |||
404 | } | |||
405 | ||||
406 | DPRINTFN(9, ("msk_miibus_readreg: i=%d, timeout=%d\n", i, | |||
407 | SK_TIMEOUT)); | |||
408 | ||||
409 | val = SK_YU_READ_2(sc_if, YUKON_SMIDR)sk_win_read_2((sc_if)->sk_softc, (((0x0084)) + 0x2800 + (( ((sc_if))->sk_port) * (0x3800 - 0x2800)))); | |||
410 | ||||
411 | DPRINTFN(9, ("msk_miibus_readreg phy=%d, reg=%#x, val=%#x\n", | |||
412 | phy, reg, val)); | |||
413 | ||||
414 | return (val); | |||
415 | } | |||
416 | ||||
417 | void | |||
418 | msk_miibus_writereg(struct device *dev, int phy, int reg, int val) | |||
419 | { | |||
420 | struct sk_if_softc *sc_if = (struct sk_if_softc *)dev; | |||
421 | int i; | |||
422 | ||||
423 | DPRINTFN(9, ("msk_miibus_writereg phy=%d reg=%#x val=%#x\n", | |||
424 | phy, reg, val)); | |||
425 | ||||
426 | SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val)sk_win_write_2((sc_if)->sk_softc, (((0x0084)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (val)); | |||
427 | SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) |sk_win_write_2((sc_if)->sk_softc, (((0x0080)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((((phy) & 0x1f) << 11) | (((reg) & 0x1f) << 6) | 0x0000 )) | |||
428 | YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE)sk_win_write_2((sc_if)->sk_softc, (((0x0080)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((((phy) & 0x1f) << 11) | (((reg) & 0x1f) << 6) | 0x0000 )); | |||
429 | ||||
430 | for (i = 0; i < SK_TIMEOUT1000; i++) { | |||
431 | DELAY(1)(*delay_func)(1); | |||
432 | if (!(SK_YU_READ_2(sc_if, YUKON_SMICR)sk_win_read_2((sc_if)->sk_softc, (((0x0080)) + 0x2800 + (( ((sc_if))->sk_port) * (0x3800 - 0x2800)))) & YU_SMICR_BUSY0x0008)) | |||
433 | break; | |||
434 | } | |||
435 | ||||
436 | if (i == SK_TIMEOUT1000) | |||
437 | printf("%s: phy write timed out\n", sc_if->sk_dev.dv_xname); | |||
438 | } | |||
439 | ||||
440 | void | |||
441 | msk_miibus_statchg(struct device *dev) | |||
442 | { | |||
443 | struct sk_if_softc *sc_if = (struct sk_if_softc *)dev; | |||
444 | struct mii_data *mii = &sc_if->sk_mii; | |||
445 | struct ifmedia_entry *ife = mii->mii_media.ifm_cur; | |||
446 | int gpcr; | |||
447 | ||||
448 | gpcr = SK_YU_READ_2(sc_if, YUKON_GPCR)sk_win_read_2((sc_if)->sk_softc, (((0x0004)) + 0x2800 + (( ((sc_if))->sk_port) * (0x3800 - 0x2800)))); | |||
449 | gpcr &= (YU_GPCR_TXEN0x1000 | YU_GPCR_RXEN0x0800); | |||
450 | ||||
451 | if (IFM_SUBTYPE(ife->ifm_media)((ife->ifm_media) & 0x00000000000000ffULL) != IFM_AUTO0ULL || | |||
452 | sc_if->sk_softc->sk_type == SK_YUKON_FE_P0xB8) { | |||
453 | /* Set speed. */ | |||
454 | gpcr |= YU_GPCR_SPEED_DIS0x0001; | |||
455 | switch (IFM_SUBTYPE(mii->mii_media_active)((mii->mii_media_active) & 0x00000000000000ffULL)) { | |||
456 | case IFM_1000_SX11: | |||
457 | case IFM_1000_LX14: | |||
458 | case IFM_1000_CX15: | |||
459 | case IFM_1000_T16: | |||
460 | gpcr |= (YU_GPCR_GIG0x0080 | YU_GPCR_SPEED0x0008); | |||
461 | break; | |||
462 | case IFM_100_TX6: | |||
463 | gpcr |= YU_GPCR_SPEED0x0008; | |||
464 | break; | |||
465 | } | |||
466 | ||||
467 | /* Set duplex. */ | |||
468 | gpcr |= YU_GPCR_DPLX_DIS0x0004; | |||
469 | if ((mii->mii_media_active & IFM_GMASK0x00ffff0000000000ULL) == IFM_FDX0x0000010000000000ULL) | |||
470 | gpcr |= YU_GPCR_DUPLEX0x0020; | |||
471 | ||||
472 | /* Disable flow control. */ | |||
473 | gpcr |= YU_GPCR_FCTL_DIS0x0002; | |||
474 | gpcr |= (YU_GPCR_FCTL_TX_DIS0x2000 | YU_GPCR_FCTL_RX_DIS0x0010); | |||
475 | } | |||
476 | ||||
477 | SK_YU_WRITE_2(sc_if, YUKON_GPCR, gpcr)sk_win_write_2((sc_if)->sk_softc, (((0x0004)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (gpcr)); | |||
478 | ||||
479 | DPRINTFN(9, ("msk_miibus_statchg: gpcr=%x\n", | |||
480 | SK_YU_READ_2(((struct sk_if_softc *)dev), YUKON_GPCR))); | |||
481 | } | |||
482 | ||||
483 | void | |||
484 | msk_iff(struct sk_if_softc *sc_if) | |||
485 | { | |||
486 | struct ifnet *ifp = &sc_if->arpcom.ac_if; | |||
487 | struct arpcom *ac = &sc_if->arpcom; | |||
488 | struct ether_multi *enm; | |||
489 | struct ether_multistep step; | |||
490 | u_int32_t hashes[2]; | |||
491 | u_int16_t rcr; | |||
492 | int h; | |||
493 | ||||
494 | rcr = SK_YU_READ_2(sc_if, YUKON_RCR)sk_win_read_2((sc_if)->sk_softc, (((0x000c)) + 0x2800 + (( ((sc_if))->sk_port) * (0x3800 - 0x2800)))); | |||
495 | rcr &= ~(YU_RCR_MUFLEN0x4000 | YU_RCR_UFLEN0x8000); | |||
496 | ifp->if_flags &= ~IFF_ALLMULTI0x200; | |||
497 | ||||
498 | /* | |||
499 | * Always accept frames destined to our station address. | |||
500 | */ | |||
501 | rcr |= YU_RCR_UFLEN0x8000; | |||
502 | ||||
503 | if (ifp->if_flags & IFF_PROMISC0x100 || ac->ac_multirangecnt > 0) { | |||
504 | ifp->if_flags |= IFF_ALLMULTI0x200; | |||
505 | if (ifp->if_flags & IFF_PROMISC0x100) | |||
506 | rcr &= ~YU_RCR_UFLEN0x8000; | |||
507 | else | |||
508 | rcr |= YU_RCR_MUFLEN0x4000; | |||
509 | hashes[0] = hashes[1] = 0xFFFFFFFF; | |||
510 | } else { | |||
511 | rcr |= YU_RCR_MUFLEN0x4000; | |||
512 | /* Program new filter. */ | |||
513 | bzero(hashes, sizeof(hashes))__builtin_bzero((hashes), (sizeof(hashes))); | |||
514 | ||||
515 | ETHER_FIRST_MULTI(step, ac, enm)do { (step).e_enm = ((&(ac)->ac_multiaddrs)->lh_first ); do { if ((((enm)) = ((step)).e_enm) != ((void *)0)) ((step )).e_enm = ((((enm)))->enm_list.le_next); } while ( 0); } while ( 0); | |||
516 | while (enm != NULL((void *)0)) { | |||
517 | h = ether_crc32_be(enm->enm_addrlo, | |||
518 | ETHER_ADDR_LEN6) & ((1 << SK_HASH_BITS6) - 1); | |||
519 | ||||
520 | if (h < 32) | |||
521 | hashes[0] |= (1 << h); | |||
522 | else | |||
523 | hashes[1] |= (1 << (h - 32)); | |||
524 | ||||
525 | ETHER_NEXT_MULTI(step, enm)do { if (((enm) = (step).e_enm) != ((void *)0)) (step).e_enm = (((enm))->enm_list.le_next); } while ( 0); | |||
526 | } | |||
527 | } | |||
528 | ||||
529 | SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff)sk_win_write_2((sc_if)->sk_softc, (((0x0034)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (hashes[0] & 0xffff)); | |||
530 | SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff)sk_win_write_2((sc_if)->sk_softc, (((0x0038)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((hashes[0] >> 16) & 0xffff)); | |||
531 | SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff)sk_win_write_2((sc_if)->sk_softc, (((0x003c)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (hashes[1] & 0xffff)); | |||
532 | SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff)sk_win_write_2((sc_if)->sk_softc, (((0x0040)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((hashes[1] >> 16) & 0xffff)); | |||
533 | SK_YU_WRITE_2(sc_if, YUKON_RCR, rcr)sk_win_write_2((sc_if)->sk_softc, (((0x000c)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (rcr)); | |||
534 | } | |||
535 | ||||
536 | int | |||
537 | msk_init_rx_ring(struct sk_if_softc *sc_if) | |||
538 | { | |||
539 | struct msk_ring_data *rd = sc_if->sk_rdata; | |||
540 | struct msk_rx_desc *r; | |||
541 | ||||
542 | memset(rd->sk_rx_ring, 0, sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT)__builtin_memset((rd->sk_rx_ring), (0), (sizeof(struct msk_rx_desc ) * 512)); | |||
543 | ||||
544 | r = &rd->sk_rx_ring[0]; | |||
545 | r->sk_addr = htole32(0)((__uint32_t)(0)); | |||
546 | r->sk_opcode = SK_Y2_RXOPC_OWN0x80 | SK_Y2_RXOPC_ADDR640x21; | |||
547 | ||||
548 | sc_if->sk_cdata.sk_rx_prod = 1; | |||
549 | sc_if->sk_cdata.sk_rx_cons = 0; | |||
550 | sc_if->sk_cdata.sk_rx_hiaddr = 0; | |||
551 | ||||
552 | /* | |||
553 | * up to two ring entries per packet, so the effective ring size is | |||
554 | * halved | |||
555 | */ | |||
556 | if_rxr_init(&sc_if->sk_cdata.sk_rx_ring, 2, (MSK_RX_RING_CNT512/2) - 1); | |||
557 | ||||
558 | msk_fill_rx_ring(sc_if); | |||
559 | return (0); | |||
560 | } | |||
561 | ||||
562 | int | |||
563 | msk_init_tx_ring(struct sk_if_softc *sc_if) | |||
564 | { | |||
565 | struct sk_softc *sc = sc_if->sk_softc; | |||
566 | struct msk_ring_data *rd = sc_if->sk_rdata; | |||
567 | struct msk_tx_desc *t; | |||
568 | int i; | |||
569 | ||||
570 | memset(rd->sk_tx_ring, 0, sizeof(struct msk_tx_desc) * MSK_TX_RING_CNT)__builtin_memset((rd->sk_tx_ring), (0), (sizeof(struct msk_tx_desc ) * 512)); | |||
571 | ||||
572 | for (i = 0; i < MSK_TX_RING_CNT512; i++) { | |||
573 | if (bus_dmamap_create(sc->sc_dmatag, sc_if->sk_pktlen,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (30), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_tx_maps[i])) | |||
574 | SK_NTXSEG, sc_if->sk_pktlen, 0,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (30), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_tx_maps[i])) | |||
575 | BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (30), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_tx_maps[i])) | |||
576 | &sc_if->sk_cdata.sk_tx_maps[i])(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (30), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_tx_maps[i]))) | |||
577 | return (ENOBUFS55); | |||
578 | } | |||
579 | ||||
580 | t = &rd->sk_tx_ring[0]; | |||
581 | t->sk_addr = htole32(0)((__uint32_t)(0)); | |||
582 | t->sk_opcode = SK_Y2_TXOPC_OWN0x80 | SK_Y2_TXOPC_ADDR640x21; | |||
583 | ||||
584 | sc_if->sk_cdata.sk_tx_prod = 1; | |||
585 | sc_if->sk_cdata.sk_tx_cons = 0; | |||
586 | sc_if->sk_cdata.sk_tx_hiaddr = 0; | |||
587 | ||||
588 | MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT, BUS_DMASYNC_PREWRITE)do { int __x, __n; __x = (0); __n = (512); if ((__x + __n) > 512) { (*((sc_if)->sk_softc->sc_dmatag)->_dmamap_sync )(((sc_if)->sk_softc->sc_dmatag), ((sc_if)->sk_ring_map ), (__builtin_offsetof(struct msk_ring_data, sk_tx_ring[(__x) ])), (sizeof(struct msk_tx_desc) * (512 - __x)), ((0x04))); __n -= (512 - __x); __x = 0; } (*((sc_if)->sk_softc->sc_dmatag )->_dmamap_sync)(((sc_if)->sk_softc->sc_dmatag), ((sc_if )->sk_ring_map), (__builtin_offsetof(struct msk_ring_data, sk_tx_ring[((__x))])), (sizeof(struct msk_tx_desc) * __n), ( (0x04))); } while ( 0); | |||
589 | ||||
590 | return (0); | |||
591 | } | |||
592 | ||||
593 | static int | |||
594 | msk_newbuf(struct sk_if_softc *sc_if) | |||
595 | { | |||
596 | struct msk_ring_data *rd = sc_if->sk_rdata; | |||
597 | struct msk_rx_desc *r; | |||
598 | struct mbuf *m; | |||
599 | bus_dmamap_t map; | |||
600 | uint64_t addr; | |||
601 | uint32_t prod, head; | |||
602 | uint32_t hiaddr; | |||
603 | unsigned int pktlen = sc_if->sk_pktlen + ETHER_ALIGN2; | |||
604 | ||||
605 | m = MCLGETL(NULL, M_DONTWAIT, pktlen)m_clget((((void *)0)), (0x0002), (pktlen)); | |||
606 | if (m == NULL((void *)0)) | |||
607 | return (0); | |||
608 | m->m_lenm_hdr.mh_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len = pktlen; | |||
609 | m_adj(m, ETHER_ALIGN2); | |||
610 | ||||
611 | prod = sc_if->sk_cdata.sk_rx_prod; | |||
612 | map = sc_if->sk_cdata.sk_rx_maps[prod]; | |||
613 | ||||
614 | if (bus_dmamap_load_mbuf(sc_if->sk_softc->sc_dmatag, map, m,(*(sc_if->sk_softc->sc_dmatag)->_dmamap_load_mbuf)(( sc_if->sk_softc->sc_dmatag), (map), (m), (0x0200|0x0001 )) | |||
615 | BUS_DMA_READ|BUS_DMA_NOWAIT)(*(sc_if->sk_softc->sc_dmatag)->_dmamap_load_mbuf)(( sc_if->sk_softc->sc_dmatag), (map), (m), (0x0200|0x0001 )) != 0) { | |||
616 | m_freem(m); | |||
617 | return (0); | |||
618 | } | |||
619 | ||||
620 | bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, map, 0,(*(sc_if->sk_softc->sc_dmatag)->_dmamap_sync)((sc_if ->sk_softc->sc_dmatag), (map), (0), (map->dm_mapsize ), (0x01)) | |||
621 | map->dm_mapsize, BUS_DMASYNC_PREREAD)(*(sc_if->sk_softc->sc_dmatag)->_dmamap_sync)((sc_if ->sk_softc->sc_dmatag), (map), (0), (map->dm_mapsize ), (0x01)); | |||
622 | ||||
623 | head = prod; | |||
624 | ||||
625 | /* high 32 bits of address */ | |||
626 | addr = map->dm_segs[0].ds_addr; | |||
627 | hiaddr = addr >> 32; | |||
628 | if (sc_if->sk_cdata.sk_rx_hiaddr != hiaddr) { | |||
629 | r = &rd->sk_rx_ring[prod]; | |||
630 | htolem32(&r->sk_addr, hiaddr)(*(__uint32_t *)(&r->sk_addr) = ((__uint32_t)(hiaddr)) ); | |||
631 | r->sk_len = htole16(0)((__uint16_t)(0)); | |||
632 | r->sk_ctl = 0; | |||
633 | r->sk_opcode = SK_Y2_RXOPC_OWN0x80 | SK_Y2_RXOPC_ADDR640x21; | |||
634 | ||||
635 | sc_if->sk_cdata.sk_rx_hiaddr = hiaddr; | |||
636 | ||||
637 | SK_INC(prod, MSK_RX_RING_CNT)(prod) = (prod + 1) % 512; | |||
638 | } | |||
639 | ||||
640 | r = &rd->sk_rx_ring[prod]; | |||
641 | htolem32(&r->sk_addr, addr)(*(__uint32_t *)(&r->sk_addr) = ((__uint32_t)(addr))); | |||
642 | htolem16(&r->sk_len, map->dm_segs[0].ds_len)(*(__uint16_t *)(&r->sk_len) = ((__uint16_t)(map->dm_segs [0].ds_len))); | |||
643 | r->sk_ctl = 0; | |||
644 | r->sk_opcode = SK_Y2_RXOPC_OWN0x80 | SK_Y2_RXOPC_PACKET0x41; | |||
645 | ||||
646 | sc_if->sk_cdata.sk_rx_maps[head] = sc_if->sk_cdata.sk_rx_maps[prod]; | |||
647 | sc_if->sk_cdata.sk_rx_maps[prod] = map; | |||
648 | ||||
649 | sc_if->sk_cdata.sk_rx_mbuf[prod] = m; | |||
650 | ||||
651 | SK_INC(prod, MSK_RX_RING_CNT)(prod) = (prod + 1) % 512; | |||
652 | sc_if->sk_cdata.sk_rx_prod = prod; | |||
653 | ||||
654 | return (1); | |||
655 | } | |||
656 | ||||
657 | /* | |||
658 | * Set media options. | |||
659 | */ | |||
660 | int | |||
661 | msk_ifmedia_upd(struct ifnet *ifp) | |||
662 | { | |||
663 | struct sk_if_softc *sc_if = ifp->if_softc; | |||
664 | ||||
665 | mii_mediachg(&sc_if->sk_mii); | |||
666 | return (0); | |||
667 | } | |||
668 | ||||
669 | /* | |||
670 | * Report current media status. | |||
671 | */ | |||
672 | void | |||
673 | msk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) | |||
674 | { | |||
675 | struct sk_if_softc *sc_if = ifp->if_softc; | |||
676 | ||||
677 | mii_pollstat(&sc_if->sk_mii); | |||
678 | ifmr->ifm_active = sc_if->sk_mii.mii_media_active; | |||
679 | ifmr->ifm_status = sc_if->sk_mii.mii_media_status; | |||
680 | } | |||
681 | ||||
682 | int | |||
683 | msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) | |||
684 | { | |||
685 | struct sk_if_softc *sc_if = ifp->if_softc; | |||
686 | struct ifreq *ifr = (struct ifreq *) data; | |||
687 | struct mii_data *mii; | |||
688 | int s, error = 0; | |||
689 | ||||
690 | s = splnet()splraise(0x4); | |||
691 | ||||
692 | switch(command) { | |||
693 | case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((12))): | |||
694 | ifp->if_flags |= IFF_UP0x1; | |||
695 | if (!(ifp->if_flags & IFF_RUNNING0x40)) | |||
696 | msk_init(sc_if); | |||
697 | break; | |||
698 | ||||
699 | case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((16))): | |||
700 | if (ifp->if_flags & IFF_UP0x1) { | |||
701 | if (ifp->if_flags & IFF_RUNNING0x40) | |||
702 | error = ENETRESET52; | |||
703 | else | |||
704 | msk_init(sc_if); | |||
705 | } else { | |||
706 | if (ifp->if_flags & IFF_RUNNING0x40) | |||
707 | msk_stop(sc_if, 0); | |||
708 | } | |||
709 | break; | |||
710 | ||||
711 | case SIOCGIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifmediareq) & 0x1fff) << 16) | ((('i')) << 8) | ((56))): | |||
712 | case SIOCSIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct ifreq) & 0x1fff) << 16) | ((('i')) << 8) | ((55))): | |||
713 | mii = &sc_if->sk_mii; | |||
714 | error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); | |||
715 | break; | |||
716 | ||||
717 | case SIOCGIFRXR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((170))): | |||
718 | error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_dataifr_ifru.ifru_data, | |||
719 | NULL((void *)0), sc_if->sk_pktlen, &sc_if->sk_cdata.sk_rx_ring); | |||
720 | break; | |||
721 | ||||
722 | default: | |||
723 | error = ether_ioctl(ifp, &sc_if->arpcom, command, data); | |||
724 | } | |||
725 | ||||
726 | if (error == ENETRESET52) { | |||
727 | if (ifp->if_flags & IFF_RUNNING0x40) | |||
728 | msk_iff(sc_if); | |||
729 | error = 0; | |||
730 | } | |||
731 | ||||
732 | splx(s)spllower(s); | |||
733 | return (error); | |||
734 | } | |||
735 | ||||
736 | /* | |||
737 | * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device | |||
738 | * IDs against our list and return a device name if we find a match. | |||
739 | */ | |||
740 | int | |||
741 | mskc_probe(struct device *parent, void *match, void *aux) | |||
742 | { | |||
743 | return (pci_matchbyid((struct pci_attach_args *)aux, mskc_devices, | |||
744 | nitems(mskc_devices)(sizeof((mskc_devices)) / sizeof((mskc_devices)[0])))); | |||
745 | } | |||
746 | ||||
747 | /* | |||
748 | * Force the GEnesis into reset, then bring it out of reset. | |||
749 | */ | |||
750 | void | |||
751 | mskc_reset(struct sk_softc *sc) | |||
752 | { | |||
753 | u_int32_t imtimer_ticks, reg1; | |||
754 | int reg; | |||
755 | unsigned int i; | |||
756 | ||||
757 | DPRINTFN(2, ("mskc_reset\n")); | |||
758 | ||||
759 | CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_RESET)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0004 )), ((0x0001)))); | |||
760 | CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_RESET)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0004 )), ((0x0004)))); | |||
761 | ||||
762 | DELAY(1000)(*delay_func)(1000); | |||
763 | CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_UNRESET)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0004 )), ((0x0002)))); | |||
764 | DELAY(2)(*delay_func)(2); | |||
765 | CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_UNRESET)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0004 )), ((0x0008)))); | |||
766 | ||||
767 | sk_win_write_1(sc, SK_TESTCTL10x0158, 2); | |||
768 | ||||
769 | if (sc->sk_type == SK_YUKON_EC_U0xB4 || sc->sk_type == SK_YUKON_EX0xB5 || | |||
770 | sc->sk_type >= SK_YUKON_FE_P0xB8) { | |||
771 | /* enable all clocks. */ | |||
772 | sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG3)((0x0080) + 0x1c00), 0); | |||
773 | reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG4)((0x0084) + 0x1c00)); | |||
774 | reg1 &= (SK_Y2_REG4_FORCE_ASPM_REQUEST0x00008000| | |||
775 | SK_Y2_REG4_ASPM_GPHY_LINK_DOWN0x00004000| | |||
776 | SK_Y2_REG4_ASPM_INT_FIFO_EMPTY0x00002000| | |||
777 | SK_Y2_REG4_ASPM_CLKRUN_REQUEST0x00001000); | |||
778 | sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG4)((0x0084) + 0x1c00), reg1); | |||
779 | ||||
780 | reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG5)((0x0088) + 0x1c00)); | |||
781 | reg1 &= SK_Y2_REG5_TIM_VMAIN_AV_MASK0x18000000; | |||
782 | sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG5)((0x0088) + 0x1c00), reg1); | |||
783 | sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_CFGREG1)((0x0094) + 0x1c00), 0); | |||
784 | ||||
785 | /* | |||
786 | * Disable status race, workaround for Yukon EC Ultra & | |||
787 | * Yukon EX. | |||
788 | */ | |||
789 | reg1 = sk_win_read_4(sc, SK_GPIO0x015C); | |||
790 | reg1 |= SK_Y2_GPIO_STAT_RACE_DIS0x00002000; | |||
791 | sk_win_write_4(sc, SK_GPIO0x015C, reg1); | |||
792 | sk_win_read_4(sc, SK_GPIO0x015C); | |||
793 | } | |||
794 | ||||
795 | reg1 = sk_win_read_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1)((0x0040) + 0x1c00)); | |||
796 | if (sc->sk_type == SK_YUKON_XL0xB3 && sc->sk_rev > SK_YUKON_XL_REV_A10x1) | |||
797 | reg1 |= (SK_Y2_REG1_PHY1_COMA0x10000000 | SK_Y2_REG1_PHY2_COMA0x20000000); | |||
798 | else | |||
799 | reg1 &= ~(SK_Y2_REG1_PHY1_COMA0x10000000 | SK_Y2_REG1_PHY2_COMA0x20000000); | |||
800 | sk_win_write_4(sc, SK_Y2_PCI_REG(SK_PCI_OURREG1)((0x0040) + 0x1c00), reg1); | |||
801 | ||||
802 | if (sc->sk_type == SK_YUKON_XL0xB3 && sc->sk_rev > SK_YUKON_XL_REV_A10x1) | |||
803 | sk_win_write_1(sc, SK_Y2_CLKGATE0x011D, | |||
804 | SK_Y2_CLKGATE_LINK1_GATE_DIS0x04 | | |||
805 | SK_Y2_CLKGATE_LINK2_GATE_DIS0x40 | | |||
806 | SK_Y2_CLKGATE_LINK1_CORE_DIS0x02 | | |||
807 | SK_Y2_CLKGATE_LINK2_CORE_DIS0x20 | | |||
808 | SK_Y2_CLKGATE_LINK1_PCI_DIS0x01 | SK_Y2_CLKGATE_LINK2_PCI_DIS0x10); | |||
809 | else | |||
810 | sk_win_write_1(sc, SK_Y2_CLKGATE0x011D, 0); | |||
811 | ||||
812 | CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0f10 )), ((0x0001)))); | |||
813 | CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_SET)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0f10 + 0x80)), ((0x0001)))); | |||
814 | DELAY(1000)(*delay_func)(1000); | |||
815 | CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0f10 )), ((0x0002)))); | |||
816 | CSR_WRITE_2(sc, SK_LINK_CTRL + SK_WIN_LEN, SK_LINK_RESET_CLEAR)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0f10 + 0x80)), ((0x0002)))); | |||
817 | ||||
818 | if (sc->sk_type == SK_YUKON_EX0xB5 || sc->sk_type == SK_YUKON_SUPR0xB9) { | |||
819 | CSR_WRITE_2(sc, SK_GMAC_CTRL, SK_GMAC_BYP_MACSECRX |(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0f00 )), ((0x00002000 | 0x00000800 | 0x00000200)))) | |||
820 | SK_GMAC_BYP_MACSECTX | SK_GMAC_BYP_RETR_FIFO)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0f00 )), ((0x00002000 | 0x00000800 | 0x00000200)))); | |||
821 | } | |||
822 | ||||
823 | sk_win_write_1(sc, SK_TESTCTL10x0158, 1); | |||
824 | ||||
825 | DPRINTFN(2, ("mskc_reset: sk_csr=%x\n", CSR_READ_1(sc, SK_CSR))); | |||
826 | DPRINTFN(2, ("mskc_reset: sk_link_ctrl=%x\n", | |||
827 | CSR_READ_2(sc, SK_LINK_CTRL))); | |||
828 | ||||
829 | /* Disable ASF */ | |||
830 | CSR_WRITE_1(sc, SK_Y2_ASF_CSR, SK_Y2_ASF_RESET)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0e68 )), ((0x08)))); | |||
831 | CSR_WRITE_2(sc, SK_CSR, SK_CSR_ASF_OFF)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0004 )), ((0x1000)))); | |||
832 | ||||
833 | /* Clear I2C IRQ noise */ | |||
834 | CSR_WRITE_4(sc, SK_I2CHWIRQ, 1)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((0x0168 )), ((1)))); | |||
835 | ||||
836 | /* Disable hardware timer */ | |||
837 | CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_STOP)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0138 )), ((0x02)))); | |||
838 | CSR_WRITE_1(sc, SK_TIMERCTL, SK_IMCTL_IRQ_CLEAR)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0138 )), ((0x01)))); | |||
839 | ||||
840 | /* Disable descriptor polling */ | |||
841 | CSR_WRITE_4(sc, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((0x0e08 )), ((0x0001)))); | |||
842 | ||||
843 | /* Disable time stamps */ | |||
844 | CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_STOP)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0e18 )), ((0x02)))); | |||
845 | CSR_WRITE_1(sc, SK_TSTAMP_CTL, SK_TSTAMP_IRQ_CLEAR)(((sc)->sk_btag)->write_1(((sc)->sk_bhandle), ((0x0e18 )), ((0x01)))); | |||
846 | ||||
847 | /* Enable RAM interface */ | |||
848 | sk_win_write_1(sc, SK_RAMCTL0x01A0, SK_RAMCTL_UNRESET0x0002); | |||
849 | for (reg = SK_TO00x0190;reg <= SK_TO110x019B; reg++) | |||
850 | sk_win_write_1(sc, reg, 36); | |||
851 | sk_win_write_1(sc, SK_RAMCTL0x01A0 + (SK_WIN_LEN0x80 / 2), SK_RAMCTL_UNRESET0x0002); | |||
852 | for (reg = SK_TO00x0190;reg <= SK_TO110x019B; reg++) | |||
853 | sk_win_write_1(sc, reg + (SK_WIN_LEN0x80 / 2), 36); | |||
854 | ||||
855 | /* | |||
856 | * Configure interrupt moderation. The moderation timer | |||
857 | * defers interrupts specified in the interrupt moderation | |||
858 | * timer mask based on the timeout specified in the interrupt | |||
859 | * moderation timer init register. Each bit in the timer | |||
860 | * register represents one tick, so to specify a timeout in | |||
861 | * microseconds, we have to multiply by the correct number of | |||
862 | * ticks-per-microsecond. | |||
863 | */ | |||
864 | switch (sc->sk_type) { | |||
865 | case SK_YUKON_EC0xB6: | |||
866 | case SK_YUKON_EC_U0xB4: | |||
867 | case SK_YUKON_EX0xB5: | |||
868 | case SK_YUKON_SUPR0xB9: | |||
869 | case SK_YUKON_ULTRA20xBA: | |||
870 | case SK_YUKON_OPTIMA0xBC: | |||
871 | case SK_YUKON_PRM0xBD: | |||
872 | case SK_YUKON_OPTIMA20xBE: | |||
873 | imtimer_ticks = SK_IMTIMER_TICKS_YUKON_EC125; | |||
874 | break; | |||
875 | case SK_YUKON_FE0xB7: | |||
876 | imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE100; | |||
877 | break; | |||
878 | case SK_YUKON_FE_P0xB8: | |||
879 | imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE_P50; | |||
880 | break; | |||
881 | case SK_YUKON_XL0xB3: | |||
882 | imtimer_ticks = SK_IMTIMER_TICKS_YUKON_XL156; | |||
883 | break; | |||
884 | default: | |||
885 | imtimer_ticks = SK_IMTIMER_TICKS_YUKON78; | |||
886 | break; | |||
887 | } | |||
888 | ||||
889 | /* Reset status ring. */ | |||
890 | for (i = 0; i < MSK_STATUS_RING_CNT2048; i++) | |||
891 | sc->sk_status_ring[i] = htole64(0)((__uint64_t)(0)); | |||
892 | sc->sk_status_idx = 0; | |||
893 | ||||
894 | sk_win_write_4(sc, SK_STAT_BMU_CSR0x0e80, SK_STAT_BMU_RESET0x00000001); | |||
895 | sk_win_write_4(sc, SK_STAT_BMU_CSR0x0e80, SK_STAT_BMU_UNRESET0x00000002); | |||
896 | ||||
897 | sk_win_write_2(sc, SK_STAT_BMU_LIDX0x0e84, MSK_STATUS_RING_CNT2048 - 1); | |||
898 | sk_win_write_4(sc, SK_STAT_BMU_ADDRLO0x0e88, | |||
899 | sc->sk_status_map->dm_segs[0].ds_addr); | |||
900 | sk_win_write_4(sc, SK_STAT_BMU_ADDRHI0x0e8c, | |||
901 | (u_int64_t)sc->sk_status_map->dm_segs[0].ds_addr >> 32); | |||
902 | sk_win_write_2(sc, SK_STAT_BMU_TX_THRESH0x0e98, 10); | |||
903 | sk_win_write_1(sc, SK_STAT_BMU_FIFOWM0x0eac, 16); | |||
904 | sk_win_write_1(sc, SK_STAT_BMU_FIFOIWM0x0ead, 16); | |||
905 | ||||
906 | #if 0 | |||
907 | sk_win_write_4(sc, SK_Y2_LEV_ITIMERINIT0x0eb0, SK_IM_USECS(100)((100) * imtimer_ticks)); | |||
908 | sk_win_write_4(sc, SK_Y2_TX_ITIMERINIT0x0ec0, SK_IM_USECS(1000)((1000) * imtimer_ticks)); | |||
909 | sk_win_write_4(sc, SK_Y2_ISR_ITIMERINIT0x0ed0, SK_IM_USECS(20)((20) * imtimer_ticks)); | |||
910 | #else | |||
911 | sk_win_write_4(sc, SK_Y2_ISR_ITIMERINIT0x0ed0, SK_IM_USECS(4)((4) * imtimer_ticks)); | |||
912 | #endif | |||
913 | ||||
914 | sk_win_write_4(sc, SK_STAT_BMU_CSR0x0e80, SK_STAT_BMU_ON0x00000008); | |||
915 | ||||
916 | sk_win_write_1(sc, SK_Y2_LEV_ITIMERCTL0x0eb8, SK_IMCTL_START0x04); | |||
917 | sk_win_write_1(sc, SK_Y2_TX_ITIMERCTL0x0ec8, SK_IMCTL_START0x04); | |||
918 | sk_win_write_1(sc, SK_Y2_ISR_ITIMERCTL0x0ed8, SK_IMCTL_START0x04); | |||
919 | } | |||
920 | ||||
921 | int | |||
922 | msk_probe(struct device *parent, void *match, void *aux) | |||
923 | { | |||
924 | struct skc_attach_args *sa = aux; | |||
925 | ||||
926 | if (sa->skc_port != SK_PORT_A0 && sa->skc_port != SK_PORT_B1) | |||
927 | return (0); | |||
928 | ||||
929 | switch (sa->skc_type) { | |||
930 | case SK_YUKON_XL0xB3: | |||
931 | case SK_YUKON_EC_U0xB4: | |||
932 | case SK_YUKON_EX0xB5: | |||
933 | case SK_YUKON_EC0xB6: | |||
934 | case SK_YUKON_FE0xB7: | |||
935 | case SK_YUKON_FE_P0xB8: | |||
936 | case SK_YUKON_SUPR0xB9: | |||
937 | case SK_YUKON_ULTRA20xBA: | |||
938 | case SK_YUKON_OPTIMA0xBC: | |||
939 | case SK_YUKON_PRM0xBD: | |||
940 | case SK_YUKON_OPTIMA20xBE: | |||
941 | return (1); | |||
942 | } | |||
943 | ||||
944 | return (0); | |||
945 | } | |||
946 | ||||
947 | void | |||
948 | msk_reset(struct sk_if_softc *sc_if) | |||
949 | { | |||
950 | /* GMAC and GPHY Reset */ | |||
951 | SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET)sk_win_write_4(sc_if->sk_softc, 0x0f00 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000001); | |||
952 | SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET)sk_win_write_4(sc_if->sk_softc, 0x0f04 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000001); | |||
953 | DELAY(1000)(*delay_func)(1000); | |||
954 | SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_CLEAR)sk_win_write_4(sc_if->sk_softc, 0x0f04 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000002); | |||
955 | SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |sk_win_write_4(sc_if->sk_softc, 0x0f00 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000010 | 0x00000008 | 0x00000002) | |||
956 | SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR)sk_win_write_4(sc_if->sk_softc, 0x0f00 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000010 | 0x00000008 | 0x00000002); | |||
957 | } | |||
958 | ||||
959 | /* | |||
960 | * Each XMAC chip is attached as a separate logical IP interface. | |||
961 | * Single port cards will have only one logical interface of course. | |||
962 | */ | |||
963 | void | |||
964 | msk_attach(struct device *parent, struct device *self, void *aux) | |||
965 | { | |||
966 | struct sk_if_softc *sc_if = (struct sk_if_softc *)self; | |||
967 | struct sk_softc *sc = (struct sk_softc *)parent; | |||
968 | struct skc_attach_args *sa = aux; | |||
969 | struct ifnet *ifp; | |||
970 | caddr_t kva; | |||
971 | int i; | |||
972 | u_int32_t chunk; | |||
973 | int mii_flags; | |||
974 | int error; | |||
975 | ||||
976 | sc_if->sk_port = sa->skc_port; | |||
977 | sc_if->sk_softc = sc; | |||
978 | sc->sk_if[sa->skc_port] = sc_if; | |||
979 | ||||
980 | DPRINTFN(2, ("begin msk_attach: port=%d\n", sc_if->sk_port)); | |||
981 | ||||
982 | /* | |||
983 | * Get station address for this interface. Note that | |||
984 | * dual port cards actually come with three station | |||
985 | * addresses: one for each port, plus an extra. The | |||
986 | * extra one is used by the SysKonnect driver software | |||
987 | * as a 'virtual' station address for when both ports | |||
988 | * are operating in failover mode. Currently we don't | |||
989 | * use this extra address. | |||
990 | */ | |||
991 | for (i = 0; i < ETHER_ADDR_LEN6; i++) | |||
992 | sc_if->arpcom.ac_enaddr[i] = | |||
993 | sk_win_read_1(sc, SK_MAC0_00x0100 + (sa->skc_port * 8) + i); | |||
994 | ||||
995 | printf(": address %s\n", | |||
996 | ether_sprintf(sc_if->arpcom.ac_enaddr)); | |||
997 | ||||
998 | /* | |||
999 | * Set up RAM buffer addresses. The Yukon2 has a small amount | |||
1000 | * of SRAM on it, somewhere between 4K and 48K. We need to | |||
1001 | * divide this up between the transmitter and receiver. We | |||
1002 | * give the receiver 2/3 of the memory (rounded down), and the | |||
1003 | * transmitter whatever remains. | |||
1004 | */ | |||
1005 | chunk = (2 * (sc->sk_ramsize / sizeof(u_int64_t)) / 3) & ~0xff; | |||
1006 | sc_if->sk_rx_ramstart = 0; | |||
1007 | sc_if->sk_rx_ramend = sc_if->sk_rx_ramstart + chunk - 1; | |||
1008 | chunk = (sc->sk_ramsize / sizeof(u_int64_t)) - chunk; | |||
1009 | sc_if->sk_tx_ramstart = sc_if->sk_rx_ramend + 1; | |||
1010 | sc_if->sk_tx_ramend = sc_if->sk_tx_ramstart + chunk - 1; | |||
1011 | ||||
1012 | DPRINTFN(2, ("msk_attach: rx_ramstart=%#x rx_ramend=%#x\n" | |||
1013 | " tx_ramstart=%#x tx_ramend=%#x\n", | |||
1014 | sc_if->sk_rx_ramstart, sc_if->sk_rx_ramend, | |||
1015 | sc_if->sk_tx_ramstart, sc_if->sk_tx_ramend)); | |||
1016 | ||||
1017 | /* Allocate the descriptor queues. */ | |||
1018 | if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct msk_ring_data),(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( sizeof(struct msk_ring_data)), ((1 << 12)), (0), (& sc_if->sk_ring_seg), (1), (&sc_if->sk_ring_nseg), ( 0x0001 | 0x1000)) | |||
1019 | PAGE_SIZE, 0, &sc_if->sk_ring_seg, 1, &sc_if->sk_ring_nseg,(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( sizeof(struct msk_ring_data)), ((1 << 12)), (0), (& sc_if->sk_ring_seg), (1), (&sc_if->sk_ring_nseg), ( 0x0001 | 0x1000)) | |||
1020 | BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( sizeof(struct msk_ring_data)), ((1 << 12)), (0), (& sc_if->sk_ring_seg), (1), (&sc_if->sk_ring_nseg), ( 0x0001 | 0x1000))) { | |||
1021 | printf(": can't alloc rx buffers\n"); | |||
1022 | goto fail; | |||
1023 | } | |||
1024 | if (bus_dmamem_map(sc->sc_dmatag, &sc_if->sk_ring_seg,(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (& sc_if->sk_ring_seg), (sc_if->sk_ring_nseg), (sizeof(struct msk_ring_data)), (&kva), (0x0001)) | |||
1025 | sc_if->sk_ring_nseg,(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (& sc_if->sk_ring_seg), (sc_if->sk_ring_nseg), (sizeof(struct msk_ring_data)), (&kva), (0x0001)) | |||
1026 | sizeof(struct msk_ring_data), &kva, BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (& sc_if->sk_ring_seg), (sc_if->sk_ring_nseg), (sizeof(struct msk_ring_data)), (&kva), (0x0001))) { | |||
1027 | printf(": can't map dma buffers (%lu bytes)\n", | |||
1028 | (ulong)sizeof(struct msk_ring_data)); | |||
1029 | goto fail_1; | |||
1030 | } | |||
1031 | if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct msk_ring_data), 1,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sizeof(struct msk_ring_data)), (1), (sizeof(struct msk_ring_data )), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_ring_map )) | |||
1032 | sizeof(struct msk_ring_data), 0,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sizeof(struct msk_ring_data)), (1), (sizeof(struct msk_ring_data )), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_ring_map )) | |||
1033 | BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sizeof(struct msk_ring_data)), (1), (sizeof(struct msk_ring_data )), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_ring_map )) | |||
1034 | &sc_if->sk_ring_map)(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sizeof(struct msk_ring_data)), (1), (sizeof(struct msk_ring_data )), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_ring_map ))) { | |||
1035 | printf(": can't create dma map\n"); | |||
1036 | goto fail_2; | |||
1037 | } | |||
1038 | if (bus_dmamap_load(sc->sc_dmatag, sc_if->sk_ring_map, kva,(*(sc->sc_dmatag)->_dmamap_load)((sc->sc_dmatag), (sc_if ->sk_ring_map), (kva), (sizeof(struct msk_ring_data)), ((( void *)0)), (0x0001)) | |||
1039 | sizeof(struct msk_ring_data), NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamap_load)((sc->sc_dmatag), (sc_if ->sk_ring_map), (kva), (sizeof(struct msk_ring_data)), ((( void *)0)), (0x0001))) { | |||
1040 | printf(": can't load dma map\n"); | |||
1041 | goto fail_3; | |||
1042 | } | |||
1043 | sc_if->sk_rdata = (struct msk_ring_data *)kva; | |||
1044 | ||||
1045 | if (sc->sk_type != SK_YUKON_FE0xB7 && | |||
1046 | sc->sk_type != SK_YUKON_FE_P0xB8) | |||
1047 | sc_if->sk_pktlen = SK_JLEN(9018 + 2); | |||
1048 | else | |||
1049 | sc_if->sk_pktlen = MCLBYTES(1 << 11); | |||
1050 | ||||
1051 | for (i = 0; i < MSK_RX_RING_CNT512; i++) { | |||
1052 | if ((error = bus_dmamap_create(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (1), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_rx_maps[i])) | |||
1053 | sc_if->sk_pktlen, 1, sc_if->sk_pktlen, 0,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (1), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_rx_maps[i])) | |||
1054 | BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (1), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_rx_maps[i])) | |||
1055 | &sc_if->sk_cdata.sk_rx_maps[i])(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( sc_if->sk_pktlen), (1), (sc_if->sk_pktlen), (0), (0x0001 | 0x0002 | 0x2000), (&sc_if->sk_cdata.sk_rx_maps[i]))) != 0) { | |||
1056 | printf("\n%s: unable to create rx DMA map %d, " | |||
1057 | "error = %d\n", sc->sk_dev.dv_xname, i, error); | |||
1058 | goto fail_4; | |||
1059 | } | |||
1060 | } | |||
1061 | ||||
1062 | ifp = &sc_if->arpcom.ac_if; | |||
1063 | ifp->if_softc = sc_if; | |||
1064 | ifp->if_flags = IFF_BROADCAST0x2 | IFF_SIMPLEX0x800 | IFF_MULTICAST0x8000; | |||
1065 | ifp->if_ioctl = msk_ioctl; | |||
1066 | ifp->if_start = msk_start; | |||
1067 | ifp->if_watchdog = msk_watchdog; | |||
1068 | if (sc->sk_type != SK_YUKON_FE0xB7 && | |||
1069 | sc->sk_type != SK_YUKON_FE_P0xB8) | |||
1070 | ifp->if_hardmtu = SK_JUMBO_MTU(9018 - ((6 * 2) + 2) - 4); | |||
1071 | ifq_init_maxlen(&ifp->if_snd, MSK_TX_RING_CNT512 - 1); | |||
1072 | bcopy(sc_if->sk_dev.dv_xname, ifp->if_xname, IFNAMSIZ16); | |||
1073 | ||||
1074 | ifp->if_capabilitiesif_data.ifi_capabilities = IFCAP_VLAN_MTU0x00000010; | |||
1075 | ||||
1076 | msk_reset(sc_if); | |||
1077 | ||||
1078 | /* | |||
1079 | * Do miibus setup. | |||
1080 | */ | |||
1081 | msk_init_yukon(sc_if); | |||
1082 | ||||
1083 | DPRINTFN(2, ("msk_attach: 1\n")); | |||
1084 | ||||
1085 | sc_if->sk_mii.mii_ifp = ifp; | |||
1086 | sc_if->sk_mii.mii_readreg = msk_miibus_readreg; | |||
1087 | sc_if->sk_mii.mii_writereg = msk_miibus_writereg; | |||
1088 | sc_if->sk_mii.mii_statchg = msk_miibus_statchg; | |||
1089 | ||||
1090 | ifmedia_init(&sc_if->sk_mii.mii_media, 0, | |||
1091 | msk_ifmedia_upd, msk_ifmedia_sts); | |||
1092 | mii_flags = MIIF_DOPAUSE0x0100; | |||
1093 | if (sc->sk_fibertype) | |||
1094 | mii_flags |= MIIF_HAVEFIBER0x0020; | |||
1095 | mii_attach(self, &sc_if->sk_mii, 0xffffffff, 0, | |||
1096 | MII_OFFSET_ANY-1, mii_flags); | |||
1097 | if (LIST_FIRST(&sc_if->sk_mii.mii_phys)((&sc_if->sk_mii.mii_phys)->lh_first) == NULL((void *)0)) { | |||
1098 | printf("%s: no PHY found!\n", sc_if->sk_dev.dv_xname); | |||
1099 | ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER0x0000000000000100ULL|IFM_MANUAL1ULL, | |||
1100 | 0, NULL((void *)0)); | |||
1101 | ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER0x0000000000000100ULL|IFM_MANUAL1ULL); | |||
1102 | } else | |||
1103 | ifmedia_set(&sc_if->sk_mii.mii_media, IFM_ETHER0x0000000000000100ULL|IFM_AUTO0ULL); | |||
1104 | ||||
1105 | timeout_set(&sc_if->sk_tick_ch, msk_tick, sc_if); | |||
1106 | timeout_set(&sc_if->sk_tick_rx, msk_fill_rx_tick, sc_if); | |||
1107 | ||||
1108 | /* | |||
1109 | * Call MI attach routines. | |||
1110 | */ | |||
1111 | if_attach(ifp); | |||
1112 | ether_ifattach(ifp); | |||
1113 | ||||
1114 | #if NKSTAT1 > 0 | |||
1115 | msk_kstat_attach(sc_if); | |||
1116 | #endif | |||
1117 | ||||
1118 | DPRINTFN(2, ("msk_attach: end\n")); | |||
1119 | return; | |||
1120 | ||||
1121 | fail_4: | |||
1122 | for (i = 0; i < MSK_RX_RING_CNT512; i++) { | |||
1123 | if (sc_if->sk_cdata.sk_rx_maps[i] != NULL((void *)0)) | |||
1124 | bus_dmamap_destroy(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag), (sc_if->sk_cdata.sk_rx_maps[i])) | |||
1125 | sc_if->sk_cdata.sk_rx_maps[i])(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag), (sc_if->sk_cdata.sk_rx_maps[i])); | |||
1126 | } | |||
1127 | ||||
1128 | fail_3: | |||
1129 | bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map)(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag), (sc_if->sk_ring_map)); | |||
1130 | fail_2: | |||
1131 | bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct msk_ring_data))(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), ( kva), (sizeof(struct msk_ring_data))); | |||
1132 | fail_1: | |||
1133 | bus_dmamem_free(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg)(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (& sc_if->sk_ring_seg), (sc_if->sk_ring_nseg)); | |||
1134 | fail: | |||
1135 | sc->sk_if[sa->skc_port] = NULL((void *)0); | |||
1136 | } | |||
1137 | ||||
1138 | int | |||
1139 | msk_detach(struct device *self, int flags) | |||
1140 | { | |||
1141 | struct sk_if_softc *sc_if = (struct sk_if_softc *)self; | |||
1142 | struct sk_softc *sc = sc_if->sk_softc; | |||
1143 | struct ifnet *ifp= &sc_if->arpcom.ac_if; | |||
1144 | ||||
1145 | if (sc->sk_if[sc_if->sk_port] == NULL((void *)0)) | |||
1146 | return (0); | |||
1147 | ||||
1148 | msk_stop(sc_if, 1); | |||
1149 | ||||
1150 | #if NKSTAT1 > 0 | |||
1151 | msk_kstat_detach(sc_if); | |||
1152 | #endif | |||
1153 | ||||
1154 | /* Detach any PHYs we might have. */ | |||
1155 | if (LIST_FIRST(&sc_if->sk_mii.mii_phys)((&sc_if->sk_mii.mii_phys)->lh_first) != NULL((void *)0)) | |||
1156 | mii_detach(&sc_if->sk_mii, MII_PHY_ANY-1, MII_OFFSET_ANY-1); | |||
1157 | ||||
1158 | /* Delete any remaining media. */ | |||
1159 | ifmedia_delete_instance(&sc_if->sk_mii.mii_media, IFM_INST_ANY((uint64_t) -1)); | |||
1160 | ||||
1161 | ether_ifdetach(ifp); | |||
1162 | if_detach(ifp); | |||
1163 | ||||
1164 | bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc_if->sk_rdata,(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), ( (caddr_t)sc_if->sk_rdata), (sizeof(struct msk_ring_data))) | |||
1165 | sizeof(struct msk_ring_data))(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), ( (caddr_t)sc_if->sk_rdata), (sizeof(struct msk_ring_data))); | |||
1166 | bus_dmamem_free(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (& sc_if->sk_ring_seg), (sc_if->sk_ring_nseg)) | |||
1167 | &sc_if->sk_ring_seg, sc_if->sk_ring_nseg)(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (& sc_if->sk_ring_seg), (sc_if->sk_ring_nseg)); | |||
1168 | bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map)(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag), (sc_if->sk_ring_map)); | |||
1169 | sc->sk_if[sc_if->sk_port] = NULL((void *)0); | |||
1170 | ||||
1171 | return (0); | |||
1172 | } | |||
1173 | ||||
1174 | int | |||
1175 | msk_activate(struct device *self, int act) | |||
1176 | { | |||
1177 | struct sk_if_softc *sc_if = (void *)self; | |||
1178 | struct ifnet *ifp = &sc_if->arpcom.ac_if; | |||
1179 | int rv = 0; | |||
1180 | ||||
1181 | switch (act) { | |||
1182 | case DVACT_RESUME4: | |||
1183 | msk_reset(sc_if); | |||
1184 | if (ifp->if_flags & IFF_RUNNING0x40) | |||
1185 | msk_init(sc_if); | |||
1186 | break; | |||
1187 | default: | |||
1188 | rv = config_activate_children(self, act); | |||
1189 | break; | |||
1190 | } | |||
1191 | return (rv); | |||
1192 | } | |||
1193 | ||||
1194 | int | |||
1195 | mskcprint(void *aux, const char *pnp) | |||
1196 | { | |||
1197 | struct skc_attach_args *sa = aux; | |||
1198 | ||||
1199 | if (pnp) | |||
1200 | printf("msk port %c at %s", | |||
1201 | (sa->skc_port == SK_PORT_A0) ? 'A' : 'B', pnp); | |||
1202 | else | |||
1203 | printf(" port %c", (sa->skc_port == SK_PORT_A0) ? 'A' : 'B'); | |||
1204 | return (UNCONF1); | |||
1205 | } | |||
1206 | ||||
1207 | /* | |||
1208 | * Attach the interface. Allocate softc structures, do ifmedia | |||
1209 | * setup and ethernet/BPF attach. | |||
1210 | */ | |||
1211 | void | |||
1212 | mskc_attach(struct device *parent, struct device *self, void *aux) | |||
1213 | { | |||
1214 | struct sk_softc *sc = (struct sk_softc *)self; | |||
1215 | struct pci_attach_args *pa = aux; | |||
1216 | struct skc_attach_args skca; | |||
1217 | pci_chipset_tag_t pc = pa->pa_pc; | |||
1218 | pcireg_t memtype; | |||
1219 | pci_intr_handle_t ih; | |||
1220 | const char *intrstr = NULL((void *)0); | |||
1221 | u_int8_t hw, pmd; | |||
1222 | char *revstr = NULL((void *)0); | |||
1223 | caddr_t kva; | |||
1224 | ||||
1225 | DPRINTFN(2, ("begin mskc_attach\n")); | |||
1226 | ||||
1227 | pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D00x0000); | |||
1228 | ||||
1229 | /* | |||
1230 | * Map control/status registers. | |||
1231 | */ | |||
1232 | memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM0x0010); | |||
1233 | if (pci_mapreg_map(pa, SK_PCI_LOMEM0x0010, memtype, 0, &sc->sk_btag, | |||
1234 | &sc->sk_bhandle, NULL((void *)0), &sc->sk_bsize, 0)) { | |||
1235 | printf(": can't map mem space\n"); | |||
1236 | return; | |||
1237 | } | |||
1238 | ||||
1239 | sc->sc_dmatag = pa->pa_dmat; | |||
1240 | ||||
1241 | sc->sk_type = sk_win_read_1(sc, SK_CHIPVER0x011B); | |||
1242 | sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG0x011A) >> 4); | |||
1243 | ||||
1244 | /* bail out here if chip is not recognized */ | |||
1245 | if (!(SK_IS_YUKON2(sc)((sc)->sk_type >= 0xB3 && (sc)->sk_type <= 0xBE))) { | |||
1246 | printf(": unknown chip type: %d\n", sc->sk_type); | |||
1247 | goto fail_1; | |||
1248 | } | |||
1249 | DPRINTFN(2, ("mskc_attach: allocate interrupt\n")); | |||
1250 | ||||
1251 | if (PCI_VENDOR(pa->pa_id)(((pa->pa_id) >> 0) & 0xffff) == PCI_VENDOR_MARVELL0x11ab) { | |||
1252 | switch (PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff)) { | |||
1253 | case PCI_PRODUCT_MARVELL_YUKON_80360x4351: | |||
1254 | case PCI_PRODUCT_MARVELL_YUKON_80530x4362: | |||
1255 | pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED0x20; | |||
1256 | } | |||
1257 | } | |||
1258 | ||||
1259 | /* Allocate interrupt */ | |||
1260 | if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) { | |||
1261 | printf(": couldn't map interrupt\n"); | |||
1262 | goto fail_1; | |||
1263 | } | |||
1264 | ||||
1265 | intrstr = pci_intr_string(pc, ih); | |||
1266 | sc->sk_intrhand = pci_intr_establish(pc, ih, IPL_NET0x4, msk_intr, sc, | |||
1267 | self->dv_xname); | |||
1268 | if (sc->sk_intrhand == NULL((void *)0)) { | |||
1269 | printf(": couldn't establish interrupt"); | |||
1270 | if (intrstr != NULL((void *)0)) | |||
1271 | printf(" at %s", intrstr); | |||
1272 | printf("\n"); | |||
1273 | goto fail_1; | |||
1274 | } | |||
1275 | sc->sk_pc = pc; | |||
1276 | ||||
1277 | if (bus_dmamem_alloc(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (2048 * sizeof(uint64_t)), (0), (& sc->sk_status_seg), (1), (&sc->sk_status_nseg), (0x0001 | 0x1000)) | |||
1278 | MSK_STATUS_RING_CNT * sizeof(uint64_t),(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (2048 * sizeof(uint64_t)), (0), (& sc->sk_status_seg), (1), (&sc->sk_status_nseg), (0x0001 | 0x1000)) | |||
1279 | MSK_STATUS_RING_CNT * sizeof(uint64_t),(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (2048 * sizeof(uint64_t)), (0), (& sc->sk_status_seg), (1), (&sc->sk_status_nseg), (0x0001 | 0x1000)) | |||
1280 | 0, &sc->sk_status_seg, 1, &sc->sk_status_nseg,(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (2048 * sizeof(uint64_t)), (0), (& sc->sk_status_seg), (1), (&sc->sk_status_nseg), (0x0001 | 0x1000)) | |||
1281 | BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (2048 * sizeof(uint64_t)), (0), (& sc->sk_status_seg), (1), (&sc->sk_status_nseg), (0x0001 | 0x1000))) { | |||
1282 | printf(": can't alloc status buffers\n"); | |||
1283 | goto fail_2; | |||
1284 | } | |||
1285 | ||||
1286 | if (bus_dmamem_map(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg), (2048 * sizeof (uint64_t)), (&kva), (0x0001)) | |||
1287 | &sc->sk_status_seg, sc->sk_status_nseg,(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg), (2048 * sizeof (uint64_t)), (&kva), (0x0001)) | |||
1288 | MSK_STATUS_RING_CNT * sizeof(uint64_t),(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg), (2048 * sizeof (uint64_t)), (&kva), (0x0001)) | |||
1289 | &kva, BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg), (2048 * sizeof (uint64_t)), (&kva), (0x0001))) { | |||
1290 | printf(": can't map dma buffers (%zu bytes)\n", | |||
1291 | MSK_STATUS_RING_CNT2048 * sizeof(uint64_t)); | |||
1292 | goto fail_3; | |||
1293 | } | |||
1294 | if (bus_dmamap_create(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (1), (2048 * sizeof(uint64_t)), (0) , (0x0001 | 0x0002 | 0x2000), (&sc->sk_status_map)) | |||
1295 | MSK_STATUS_RING_CNT * sizeof(uint64_t), 1,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (1), (2048 * sizeof(uint64_t)), (0) , (0x0001 | 0x0002 | 0x2000), (&sc->sk_status_map)) | |||
1296 | MSK_STATUS_RING_CNT * sizeof(uint64_t), 0,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (1), (2048 * sizeof(uint64_t)), (0) , (0x0001 | 0x0002 | 0x2000), (&sc->sk_status_map)) | |||
1297 | BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (1), (2048 * sizeof(uint64_t)), (0) , (0x0001 | 0x0002 | 0x2000), (&sc->sk_status_map)) | |||
1298 | &sc->sk_status_map)(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), ( 2048 * sizeof(uint64_t)), (1), (2048 * sizeof(uint64_t)), (0) , (0x0001 | 0x0002 | 0x2000), (&sc->sk_status_map))) { | |||
1299 | printf(": can't create dma map\n"); | |||
1300 | goto fail_4; | |||
1301 | } | |||
1302 | if (bus_dmamap_load(sc->sc_dmatag, sc->sk_status_map, kva,(*(sc->sc_dmatag)->_dmamap_load)((sc->sc_dmatag), (sc ->sk_status_map), (kva), (2048 * sizeof(uint64_t)), (((void *)0)), (0x0001)) | |||
1303 | MSK_STATUS_RING_CNT * sizeof(uint64_t),(*(sc->sc_dmatag)->_dmamap_load)((sc->sc_dmatag), (sc ->sk_status_map), (kva), (2048 * sizeof(uint64_t)), (((void *)0)), (0x0001)) | |||
1304 | NULL, BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamap_load)((sc->sc_dmatag), (sc ->sk_status_map), (kva), (2048 * sizeof(uint64_t)), (((void *)0)), (0x0001))) { | |||
1305 | printf(": can't load dma map\n"); | |||
1306 | goto fail_5; | |||
1307 | } | |||
1308 | sc->sk_status_ring = (uint64_t *)kva; | |||
1309 | ||||
1310 | /* Reset the adapter. */ | |||
1311 | mskc_reset(sc); | |||
1312 | ||||
1313 | sc->sk_ramsize = sk_win_read_1(sc, SK_EPROM00x011C) * 4096; | |||
1314 | DPRINTFN(2, ("mskc_attach: ramsize=%dK\n", sc->sk_ramsize / 1024)); | |||
1315 | ||||
1316 | pmd = sk_win_read_1(sc, SK_PMDTYPE0x0119); | |||
1317 | if (pmd == 'L' || pmd == 'S' || pmd == 'P') | |||
1318 | sc->sk_fibertype = 1; | |||
1319 | ||||
1320 | switch (sc->sk_type) { | |||
1321 | case SK_YUKON_XL0xB3: | |||
1322 | sc->sk_name = "Yukon-2 XL"; | |||
1323 | break; | |||
1324 | case SK_YUKON_EC_U0xB4: | |||
1325 | sc->sk_name = "Yukon-2 EC Ultra"; | |||
1326 | break; | |||
1327 | case SK_YUKON_EX0xB5: | |||
1328 | sc->sk_name = "Yukon-2 Extreme"; | |||
1329 | break; | |||
1330 | case SK_YUKON_EC0xB6: | |||
1331 | sc->sk_name = "Yukon-2 EC"; | |||
1332 | break; | |||
1333 | case SK_YUKON_FE0xB7: | |||
1334 | sc->sk_name = "Yukon-2 FE"; | |||
1335 | break; | |||
1336 | case SK_YUKON_FE_P0xB8: | |||
1337 | sc->sk_name = "Yukon-2 FE+"; | |||
1338 | break; | |||
1339 | case SK_YUKON_SUPR0xB9: | |||
1340 | sc->sk_name = "Yukon-2 Supreme"; | |||
1341 | break; | |||
1342 | case SK_YUKON_ULTRA20xBA: | |||
1343 | sc->sk_name = "Yukon-2 Ultra 2"; | |||
1344 | break; | |||
1345 | case SK_YUKON_OPTIMA0xBC: | |||
1346 | sc->sk_name = "Yukon-2 Optima"; | |||
1347 | break; | |||
1348 | case SK_YUKON_PRM0xBD: | |||
1349 | sc->sk_name = "Yukon-2 Optima Prime"; | |||
1350 | break; | |||
1351 | case SK_YUKON_OPTIMA20xBE: | |||
1352 | sc->sk_name = "Yukon-2 Optima 2"; | |||
1353 | break; | |||
1354 | default: | |||
1355 | sc->sk_name = "Yukon (Unknown)"; | |||
1356 | } | |||
1357 | ||||
1358 | if (sc->sk_type == SK_YUKON_XL0xB3) { | |||
1359 | switch (sc->sk_rev) { | |||
1360 | case SK_YUKON_XL_REV_A00x0: | |||
1361 | revstr = "A0"; | |||
1362 | break; | |||
1363 | case SK_YUKON_XL_REV_A10x1: | |||
1364 | revstr = "A1"; | |||
1365 | break; | |||
1366 | case SK_YUKON_XL_REV_A20x2: | |||
1367 | revstr = "A2"; | |||
1368 | break; | |||
1369 | case SK_YUKON_XL_REV_A30x3: | |||
1370 | revstr = "A3"; | |||
1371 | break; | |||
1372 | default: | |||
1373 | ; | |||
1374 | } | |||
1375 | } | |||
1376 | ||||
1377 | if (sc->sk_type == SK_YUKON_EC0xB6) { | |||
1378 | switch (sc->sk_rev) { | |||
1379 | case SK_YUKON_EC_REV_A10x0: | |||
1380 | revstr = "A1"; | |||
1381 | break; | |||
1382 | case SK_YUKON_EC_REV_A20x1: | |||
1383 | revstr = "A2"; | |||
1384 | break; | |||
1385 | case SK_YUKON_EC_REV_A30x2: | |||
1386 | revstr = "A3"; | |||
1387 | break; | |||
1388 | default: | |||
1389 | ; | |||
1390 | } | |||
1391 | } | |||
1392 | ||||
1393 | if (sc->sk_type == SK_YUKON_EC_U0xB4) { | |||
1394 | switch (sc->sk_rev) { | |||
1395 | case SK_YUKON_EC_U_REV_A00x1: | |||
1396 | revstr = "A0"; | |||
1397 | break; | |||
1398 | case SK_YUKON_EC_U_REV_A10x2: | |||
1399 | revstr = "A1"; | |||
1400 | break; | |||
1401 | case SK_YUKON_EC_U_REV_B00x3: | |||
1402 | revstr = "B0"; | |||
1403 | break; | |||
1404 | case SK_YUKON_EC_U_REV_B10x5: | |||
1405 | revstr = "B1"; | |||
1406 | break; | |||
1407 | default: | |||
1408 | ; | |||
1409 | } | |||
1410 | } | |||
1411 | ||||
1412 | if (sc->sk_type == SK_YUKON_FE0xB7) { | |||
1413 | switch (sc->sk_rev) { | |||
1414 | case SK_YUKON_FE_REV_A10x1: | |||
1415 | revstr = "A1"; | |||
1416 | break; | |||
1417 | case SK_YUKON_FE_REV_A20x2: | |||
1418 | revstr = "A2"; | |||
1419 | break; | |||
1420 | default: | |||
1421 | ; | |||
1422 | } | |||
1423 | } | |||
1424 | ||||
1425 | if (sc->sk_type == SK_YUKON_FE_P0xB8 && sc->sk_rev == SK_YUKON_FE_P_REV_A00x0) | |||
1426 | revstr = "A0"; | |||
1427 | ||||
1428 | if (sc->sk_type == SK_YUKON_EX0xB5) { | |||
1429 | switch (sc->sk_rev) { | |||
1430 | case SK_YUKON_EX_REV_A00x1: | |||
1431 | revstr = "A0"; | |||
1432 | break; | |||
1433 | case SK_YUKON_EX_REV_B00x2: | |||
1434 | revstr = "B0"; | |||
1435 | break; | |||
1436 | default: | |||
1437 | ; | |||
1438 | } | |||
1439 | } | |||
1440 | ||||
1441 | if (sc->sk_type == SK_YUKON_SUPR0xB9) { | |||
1442 | switch (sc->sk_rev) { | |||
1443 | case SK_YUKON_SUPR_REV_A00x0: | |||
1444 | revstr = "A0"; | |||
1445 | break; | |||
1446 | case SK_YUKON_SUPR_REV_B00x1: | |||
1447 | revstr = "B0"; | |||
1448 | break; | |||
1449 | case SK_YUKON_SUPR_REV_B10x3: | |||
1450 | revstr = "B1"; | |||
1451 | break; | |||
1452 | default: | |||
1453 | ; | |||
1454 | } | |||
1455 | } | |||
1456 | ||||
1457 | if (sc->sk_type == SK_YUKON_PRM0xBD) { | |||
1458 | switch (sc->sk_rev) { | |||
1459 | case SK_YUKON_PRM_REV_Z10x1: | |||
1460 | revstr = "Z1"; | |||
1461 | break; | |||
1462 | case SK_YUKON_PRM_REV_A00x2: | |||
1463 | revstr = "A0"; | |||
1464 | break; | |||
1465 | default: | |||
1466 | ; | |||
1467 | } | |||
1468 | } | |||
1469 | ||||
1470 | /* Announce the product name. */ | |||
1471 | printf(", %s", sc->sk_name); | |||
1472 | if (revstr != NULL((void *)0)) | |||
1473 | printf(" rev. %s", revstr); | |||
1474 | printf(" (0x%x): %s\n", sc->sk_rev, intrstr); | |||
1475 | ||||
1476 | sc->sk_macs = 1; | |||
1477 | ||||
1478 | hw = sk_win_read_1(sc, SK_Y2_HWRES0x011E); | |||
1479 | if ((hw & SK_Y2_HWRES_LINK_MASK(0x01 | 0x02)) == SK_Y2_HWRES_LINK_DUAL(0x01 | 0x02)) { | |||
1480 | if ((sk_win_read_1(sc, SK_Y2_CLKGATE0x011D) & | |||
1481 | SK_Y2_CLKGATE_LINK2_INACTIVE0x80) == 0) | |||
1482 | sc->sk_macs++; | |||
1483 | } | |||
1484 | ||||
1485 | skca.skc_port = SK_PORT_A0; | |||
1486 | skca.skc_type = sc->sk_type; | |||
1487 | skca.skc_rev = sc->sk_rev; | |||
1488 | (void)config_found(&sc->sk_dev, &skca, mskcprint)config_found_sm((&sc->sk_dev), (&skca), (mskcprint ), ((void *)0)); | |||
1489 | ||||
1490 | if (sc->sk_macs > 1) { | |||
1491 | skca.skc_port = SK_PORT_B1; | |||
1492 | skca.skc_type = sc->sk_type; | |||
1493 | skca.skc_rev = sc->sk_rev; | |||
1494 | (void)config_found(&sc->sk_dev, &skca, mskcprint)config_found_sm((&sc->sk_dev), (&skca), (mskcprint ), ((void *)0)); | |||
1495 | } | |||
1496 | ||||
1497 | /* Turn on the 'driver is loaded' LED. */ | |||
1498 | CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON)(((sc)->sk_btag)->write_2(((sc)->sk_bhandle), ((0x0006 )), ((0x02)))); | |||
1499 | ||||
1500 | return; | |||
1501 | ||||
1502 | fail_4: | |||
1503 | bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sk_status_ring,(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), ( (caddr_t)sc->sk_status_ring), (2048 * sizeof(uint64_t))) | |||
1504 | MSK_STATUS_RING_CNT * sizeof(uint64_t))(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), ( (caddr_t)sc->sk_status_ring), (2048 * sizeof(uint64_t))); | |||
1505 | fail_3: | |||
1506 | bus_dmamem_free(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg)) | |||
1507 | &sc->sk_status_seg, sc->sk_status_nseg)(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg)); | |||
1508 | sc->sk_status_nseg = 0; | |||
1509 | fail_5: | |||
1510 | bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map)(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag), (sc->sk_status_map)); | |||
1511 | fail_2: | |||
1512 | pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand); | |||
1513 | sc->sk_intrhand = NULL((void *)0); | |||
1514 | fail_1: | |||
1515 | bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize); | |||
1516 | sc->sk_bsize = 0; | |||
1517 | } | |||
1518 | ||||
1519 | int | |||
1520 | mskc_detach(struct device *self, int flags) | |||
1521 | { | |||
1522 | struct sk_softc *sc = (struct sk_softc *)self; | |||
1523 | int rv; | |||
1524 | ||||
1525 | if (sc->sk_intrhand) | |||
1526 | pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand); | |||
1527 | ||||
1528 | rv = config_detach_children(self, flags); | |||
1529 | if (rv != 0) | |||
1530 | return (rv); | |||
1531 | ||||
1532 | if (sc->sk_status_nseg > 0) { | |||
1533 | bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map)(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag), (sc->sk_status_map)); | |||
1534 | bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sk_status_ring,(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), ( (caddr_t)sc->sk_status_ring), (2048 * sizeof(uint64_t))) | |||
1535 | MSK_STATUS_RING_CNT * sizeof(uint64_t))(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), ( (caddr_t)sc->sk_status_ring), (2048 * sizeof(uint64_t))); | |||
1536 | bus_dmamem_free(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg)) | |||
1537 | &sc->sk_status_seg, sc->sk_status_nseg)(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (& sc->sk_status_seg), (sc->sk_status_nseg)); | |||
1538 | } | |||
1539 | ||||
1540 | if (sc->sk_bsize > 0) | |||
1541 | bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize); | |||
1542 | ||||
1543 | return(0); | |||
1544 | } | |||
1545 | ||||
1546 | int | |||
1547 | mskc_activate(struct device *self, int act) | |||
1548 | { | |||
1549 | struct sk_softc *sc = (void *)self; | |||
1550 | int rv = 0; | |||
1551 | ||||
1552 | switch (act) { | |||
1553 | case DVACT_RESUME4: | |||
1554 | mskc_reset(sc); | |||
1555 | rv = config_activate_children(self, act); | |||
1556 | break; | |||
1557 | default: | |||
1558 | rv = config_activate_children(self, act); | |||
1559 | break; | |||
1560 | } | |||
1561 | return (rv); | |||
1562 | } | |||
1563 | ||||
1564 | static unsigned int | |||
1565 | msk_encap(struct sk_if_softc *sc_if, struct mbuf *m, uint32_t prod) | |||
1566 | { | |||
1567 | struct sk_softc *sc = sc_if->sk_softc; | |||
1568 | struct msk_ring_data *rd = sc_if->sk_rdata; | |||
1569 | struct msk_tx_desc *t; | |||
1570 | bus_dmamap_t map; | |||
1571 | uint64_t addr; | |||
1572 | uint32_t hiaddr; | |||
1573 | uint32_t next, last; | |||
1574 | uint8_t opcode; | |||
1575 | unsigned int entries = 0; | |||
1576 | int i; | |||
1577 | ||||
1578 | map = sc_if->sk_cdata.sk_tx_maps[prod]; | |||
1579 | ||||
1580 | switch (bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,(*(sc->sc_dmatag)->_dmamap_load_mbuf)((sc->sc_dmatag ), (map), (m), (0x0100 | 0x0001)) | |||
1581 | BUS_DMA_STREAMING | BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamap_load_mbuf)((sc->sc_dmatag ), (map), (m), (0x0100 | 0x0001))) { | |||
1582 | case 0: | |||
1583 | break; | |||
1584 | case EFBIG27: /* mbuf chain is too fragmented */ | |||
1585 | if (m_defrag(m, M_DONTWAIT0x0002) == 0 && | |||
1586 | bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,(*(sc->sc_dmatag)->_dmamap_load_mbuf)((sc->sc_dmatag ), (map), (m), (0x0100 | 0x0001)) | |||
1587 | BUS_DMA_STREAMING | BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamap_load_mbuf)((sc->sc_dmatag ), (map), (m), (0x0100 | 0x0001)) == 0) | |||
1588 | break; | |||
1589 | /* FALLTHROUGH */ | |||
1590 | default: | |||
1591 | return (0); | |||
1592 | } | |||
1593 | ||||
1594 | bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x04)) | |||
1595 | BUS_DMASYNC_PREWRITE)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x04)); | |||
1596 | ||||
1597 | opcode = SK_Y2_TXOPC_OWN0x80 | SK_Y2_TXOPC_PACKET0x41; | |||
1598 | next = prod; | |||
1599 | for (i = 0; i < map->dm_nsegs; i++) { | |||
1600 | /* high 32 bits of address */ | |||
1601 | addr = map->dm_segs[i].ds_addr; | |||
1602 | hiaddr = addr >> 32; | |||
1603 | if (sc_if->sk_cdata.sk_tx_hiaddr != hiaddr) { | |||
1604 | t = &rd->sk_tx_ring[next]; | |||
1605 | htolem32(&t->sk_addr, hiaddr)(*(__uint32_t *)(&t->sk_addr) = ((__uint32_t)(hiaddr)) ); | |||
1606 | t->sk_opcode = SK_Y2_TXOPC_OWN0x80 | SK_Y2_TXOPC_ADDR640x21; | |||
1607 | ||||
1608 | sc_if->sk_cdata.sk_tx_hiaddr = hiaddr; | |||
1609 | ||||
1610 | SK_INC(next, MSK_TX_RING_CNT)(next) = (next + 1) % 512; | |||
1611 | entries++; | |||
1612 | } | |||
1613 | ||||
1614 | /* low 32 bits of address + length */ | |||
1615 | t = &rd->sk_tx_ring[next]; | |||
1616 | htolem32(&t->sk_addr, addr)(*(__uint32_t *)(&t->sk_addr) = ((__uint32_t)(addr))); | |||
1617 | htolem16(&t->sk_len, map->dm_segs[i].ds_len)(*(__uint16_t *)(&t->sk_len) = ((__uint16_t)(map->dm_segs [i].ds_len))); | |||
1618 | t->sk_ctl = 0; | |||
1619 | t->sk_opcode = opcode; | |||
1620 | ||||
1621 | last = next; | |||
1622 | SK_INC(next, MSK_TX_RING_CNT)(next) = (next + 1) % 512; | |||
1623 | entries++; | |||
1624 | ||||
1625 | opcode = SK_Y2_TXOPC_OWN0x80 | SK_Y2_TXOPC_BUFFER0x40; | |||
1626 | } | |||
1627 | t->sk_ctl = SK_Y2_TXCTL_LASTFRAG0x80; | |||
1628 | ||||
1629 | sc_if->sk_cdata.sk_tx_maps[prod] = sc_if->sk_cdata.sk_tx_maps[last]; | |||
1630 | sc_if->sk_cdata.sk_tx_maps[last] = map; | |||
1631 | sc_if->sk_cdata.sk_tx_mbuf[last] = m; | |||
1632 | ||||
1633 | return (entries); | |||
1634 | } | |||
1635 | ||||
1636 | void | |||
1637 | msk_start(struct ifnet *ifp) | |||
1638 | { | |||
1639 | struct sk_if_softc *sc_if = ifp->if_softc; | |||
1640 | struct mbuf *m = NULL((void *)0); | |||
1641 | uint32_t prod, free, used; | |||
1642 | int post = 0; | |||
1643 | ||||
1644 | prod = sc_if->sk_cdata.sk_tx_prod; | |||
1645 | free = sc_if->sk_cdata.sk_tx_cons; | |||
1646 | if (free <= prod) | |||
1647 | free += MSK_TX_RING_CNT512; | |||
1648 | free -= prod; | |||
1649 | ||||
1650 | MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT, BUS_DMASYNC_POSTWRITE)do { int __x, __n; __x = (0); __n = (512); if ((__x + __n) > 512) { (*((sc_if)->sk_softc->sc_dmatag)->_dmamap_sync )(((sc_if)->sk_softc->sc_dmatag), ((sc_if)->sk_ring_map ), (__builtin_offsetof(struct msk_ring_data, sk_tx_ring[(__x) ])), (sizeof(struct msk_tx_desc) * (512 - __x)), ((0x08))); __n -= (512 - __x); __x = 0; } (*((sc_if)->sk_softc->sc_dmatag )->_dmamap_sync)(((sc_if)->sk_softc->sc_dmatag), ((sc_if )->sk_ring_map), (__builtin_offsetof(struct msk_ring_data, sk_tx_ring[((__x))])), (sizeof(struct msk_tx_desc) * __n), ( (0x08))); } while ( 0); | |||
1651 | ||||
1652 | for (;;) { | |||
1653 | if (free <= SK_NTXSEG30 * 2) { | |||
1654 | ifq_set_oactive(&ifp->if_snd); | |||
1655 | break; | |||
1656 | } | |||
1657 | ||||
1658 | m = ifq_dequeue(&ifp->if_snd); | |||
1659 | if (m == NULL((void *)0)) | |||
1660 | break; | |||
1661 | ||||
1662 | used = msk_encap(sc_if, m, prod); | |||
1663 | if (used == 0) { | |||
1664 | m_freem(m); | |||
1665 | continue; | |||
1666 | } | |||
1667 | ||||
1668 | free -= used; | |||
1669 | prod += used; | |||
1670 | prod &= MSK_TX_RING_CNT512 - 1; | |||
1671 | ||||
1672 | #if NBPFILTER1 > 0 | |||
1673 | if (ifp->if_bpf) | |||
1674 | bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1)); | |||
1675 | #endif | |||
1676 | post = 1; | |||
1677 | } | |||
1678 | ||||
1679 | MSK_CDTXSYNC(sc_if, 0, MSK_TX_RING_CNT, BUS_DMASYNC_PREWRITE)do { int __x, __n; __x = (0); __n = (512); if ((__x + __n) > 512) { (*((sc_if)->sk_softc->sc_dmatag)->_dmamap_sync )(((sc_if)->sk_softc->sc_dmatag), ((sc_if)->sk_ring_map ), (__builtin_offsetof(struct msk_ring_data, sk_tx_ring[(__x) ])), (sizeof(struct msk_tx_desc) * (512 - __x)), ((0x04))); __n -= (512 - __x); __x = 0; } (*((sc_if)->sk_softc->sc_dmatag )->_dmamap_sync)(((sc_if)->sk_softc->sc_dmatag), ((sc_if )->sk_ring_map), (__builtin_offsetof(struct msk_ring_data, sk_tx_ring[((__x))])), (sizeof(struct msk_tx_desc) * __n), ( (0x04))); } while ( 0); | |||
1680 | ||||
1681 | if (post == 0) | |||
1682 | return; | |||
1683 | ||||
1684 | /* Transmit */ | |||
1685 | sc_if->sk_cdata.sk_tx_prod = prod; | |||
1686 | SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_PUTIDX, prod)sk_win_write_2(sc_if->sk_softc, 0x06E4 + ((sc_if->sk_port * (1 + 1)) * 0x80), prod); | |||
1687 | ||||
1688 | /* Set a timeout in case the chip goes out to lunch. */ | |||
1689 | ifp->if_timer = MSK_TX_TIMEOUT5; | |||
1690 | } | |||
1691 | ||||
1692 | void | |||
1693 | msk_watchdog(struct ifnet *ifp) | |||
1694 | { | |||
1695 | struct sk_if_softc *sc_if = ifp->if_softc; | |||
1696 | ||||
1697 | if (sc_if->sk_cdata.sk_tx_prod != sc_if->sk_cdata.sk_tx_cons) { | |||
1698 | printf("%s: watchdog timeout\n", sc_if->sk_dev.dv_xname); | |||
1699 | ||||
1700 | ifp->if_oerrorsif_data.ifi_oerrors++; | |||
1701 | ||||
1702 | /* XXX Resets both ports; we shouldn't do that. */ | |||
1703 | mskc_reset(sc_if->sk_softc); | |||
1704 | msk_reset(sc_if); | |||
1705 | msk_init(sc_if); | |||
1706 | } | |||
1707 | } | |||
1708 | ||||
1709 | static inline int | |||
1710 | msk_rxvalid(struct sk_softc *sc, u_int32_t stat, u_int32_t len) | |||
1711 | { | |||
1712 | if ((stat & (YU_RXSTAT_CRCERR0x00000002 | YU_RXSTAT_LONGERR0x00000010 | | |||
1713 | YU_RXSTAT_MIIERR0x00000020 | YU_RXSTAT_BADFC0x00000040 | YU_RXSTAT_GOODFC0x00000080 | | |||
1714 | YU_RXSTAT_JABBER0x00001000)) != 0 || | |||
1715 | (stat & YU_RXSTAT_RXOK0x00000100) != YU_RXSTAT_RXOK0x00000100 || | |||
1716 | YU_RXSTAT_BYTES(stat)((stat) >> 16) != len) | |||
1717 | return (0); | |||
1718 | ||||
1719 | return (1); | |||
1720 | } | |||
1721 | ||||
1722 | void | |||
1723 | msk_rxeof(struct sk_if_softc *sc_if, struct mbuf_list *ml, | |||
1724 | uint16_t len, uint32_t rxstat) | |||
1725 | { | |||
1726 | struct sk_softc *sc = sc_if->sk_softc; | |||
1727 | struct ifnet *ifp = &sc_if->arpcom.ac_if; | |||
1728 | struct mbuf *m = NULL((void *)0); | |||
1729 | int prod, cons, tail; | |||
1730 | bus_dmamap_t map; | |||
1731 | ||||
1732 | prod = sc_if->sk_cdata.sk_rx_prod; | |||
1733 | cons = sc_if->sk_cdata.sk_rx_cons; | |||
1734 | ||||
1735 | while (cons != prod) { | |||
1736 | tail = cons; | |||
1737 | SK_INC(cons, MSK_RX_RING_CNT)(cons) = (cons + 1) % 512; | |||
1738 | ||||
1739 | m = sc_if->sk_cdata.sk_rx_mbuf[tail]; | |||
1740 | if (m != NULL((void *)0)) { | |||
1741 | /* found it */ | |||
1742 | break; | |||
1743 | } | |||
1744 | } | |||
1745 | sc_if->sk_cdata.sk_rx_cons = cons; | |||
1746 | ||||
1747 | if (m == NULL((void *)0)) { | |||
1748 | /* maybe if ADDR64 is consumed? */ | |||
1749 | return; | |||
1750 | } | |||
1751 | ||||
1752 | sc_if->sk_cdata.sk_rx_mbuf[tail] = NULL((void *)0); | |||
1753 | ||||
1754 | map = sc_if->sk_cdata.sk_rx_maps[tail]; | |||
1755 | if_rxr_put(&sc_if->sk_cdata.sk_rx_ring, 1)do { (&sc_if->sk_cdata.sk_rx_ring)->rxr_alive -= (1 ); } while (0); | |||
1756 | ||||
1757 | bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, map, 0, map->dm_mapsize,(*(sc_if->sk_softc->sc_dmatag)->_dmamap_sync)((sc_if ->sk_softc->sc_dmatag), (map), (0), (map->dm_mapsize ), (0x02)) | |||
1758 | BUS_DMASYNC_POSTREAD)(*(sc_if->sk_softc->sc_dmatag)->_dmamap_sync)((sc_if ->sk_softc->sc_dmatag), (map), (0), (map->dm_mapsize ), (0x02)); | |||
1759 | bus_dmamap_unload(sc_if->sk_softc->sc_dmatag, map)(*(sc_if->sk_softc->sc_dmatag)->_dmamap_unload)((sc_if ->sk_softc->sc_dmatag), (map)); | |||
1760 | ||||
1761 | if (len < SK_MIN_FRAMELEN(64 - 4) || len > SK_JUMBO_FRAMELEN9018 || | |||
1762 | msk_rxvalid(sc, rxstat, len) == 0) { | |||
1763 | ifp->if_ierrorsif_data.ifi_ierrors++; | |||
1764 | m_freem(m); | |||
1765 | return; | |||
1766 | } | |||
1767 | ||||
1768 | m->m_pkthdrM_dat.MH.MH_pkthdr.len = m->m_lenm_hdr.mh_len = len; | |||
1769 | ||||
1770 | ml_enqueue(ml, m); | |||
1771 | } | |||
1772 | ||||
1773 | void | |||
1774 | msk_txeof(struct sk_if_softc *sc_if, unsigned int prod) | |||
1775 | { | |||
1776 | struct ifnet *ifp = &sc_if->arpcom.ac_if; | |||
1777 | struct sk_softc *sc = sc_if->sk_softc; | |||
1778 | uint32_t cons; | |||
1779 | struct mbuf *m; | |||
1780 | bus_dmamap_t map; | |||
1781 | ||||
1782 | /* | |||
1783 | * Go through our tx ring and free mbufs for those | |||
1784 | * frames that have been sent. | |||
1785 | */ | |||
1786 | cons = sc_if->sk_cdata.sk_tx_cons; | |||
1787 | ||||
1788 | if (cons == prod) | |||
1789 | return; | |||
1790 | ||||
1791 | while (cons != prod) { | |||
1792 | m = sc_if->sk_cdata.sk_tx_mbuf[cons]; | |||
1793 | if (m != NULL((void *)0)) { | |||
1794 | sc_if->sk_cdata.sk_tx_mbuf[cons] = NULL((void *)0); | |||
1795 | ||||
1796 | map = sc_if->sk_cdata.sk_tx_maps[cons]; | |||
1797 | bus_dmamap_sync(sc->sc_dmatag, map, 0,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x08)) | |||
1798 | map->dm_mapsize, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x08)); | |||
1799 | bus_dmamap_unload(sc->sc_dmatag, map)(*(sc->sc_dmatag)->_dmamap_unload)((sc->sc_dmatag), ( map)); | |||
1800 | ||||
1801 | m_freem(m); | |||
1802 | } | |||
1803 | ||||
1804 | SK_INC(cons, MSK_TX_RING_CNT)(cons) = (cons + 1) % 512; | |||
1805 | } | |||
1806 | if (cons == sc_if->sk_cdata.sk_tx_prod) | |||
1807 | ifp->if_timer = 0; | |||
1808 | ||||
1809 | sc_if->sk_cdata.sk_tx_cons = cons; | |||
1810 | ||||
1811 | if (ifq_is_oactive(&ifp->if_snd)) | |||
1812 | ifq_restart(&ifp->if_snd); | |||
1813 | } | |||
1814 | ||||
1815 | void | |||
1816 | msk_fill_rx_ring(struct sk_if_softc *sc_if) | |||
1817 | { | |||
1818 | u_int slots, used; | |||
1819 | ||||
1820 | slots = if_rxr_get(&sc_if->sk_cdata.sk_rx_ring, MSK_RX_RING_CNT512/2); | |||
1821 | ||||
1822 | MSK_CDRXSYNC(sc_if, 0, BUS_DMASYNC_POSTWRITE)do { (*((sc_if)->sk_softc->sc_dmatag)->_dmamap_sync) (((sc_if)->sk_softc->sc_dmatag), ((sc_if)->sk_ring_map ), (__builtin_offsetof(struct msk_ring_data, sk_rx_ring[((0)) ])), (sizeof(struct msk_rx_desc)), ((0x08))); } while ( 0); /* XXX */ | |||
1823 | while (slots > 0) { | |||
1824 | used = msk_newbuf(sc_if); | |||
1825 | if (used == 0) | |||
1826 | break; | |||
1827 | ||||
1828 | slots -= used; | |||
1829 | } | |||
1830 | MSK_CDRXSYNC(sc_if, 0, BUS_DMASYNC_PREWRITE)do { (*((sc_if)->sk_softc->sc_dmatag)->_dmamap_sync) (((sc_if)->sk_softc->sc_dmatag), ((sc_if)->sk_ring_map ), (__builtin_offsetof(struct msk_ring_data, sk_rx_ring[((0)) ])), (sizeof(struct msk_rx_desc)), ((0x04))); } while ( 0); /* XXX */ | |||
1831 | ||||
1832 | if_rxr_put(&sc_if->sk_cdata.sk_rx_ring, slots)do { (&sc_if->sk_cdata.sk_rx_ring)->rxr_alive -= (slots ); } while (0); | |||
1833 | if (if_rxr_inuse(&sc_if->sk_cdata.sk_rx_ring)((&sc_if->sk_cdata.sk_rx_ring)->rxr_alive) == 0) | |||
1834 | timeout_add(&sc_if->sk_tick_rx, 1); | |||
1835 | } | |||
1836 | ||||
1837 | void | |||
1838 | msk_fill_rx_tick(void *xsc_if) | |||
1839 | { | |||
1840 | struct sk_if_softc *sc_if = xsc_if; | |||
1841 | int s; | |||
1842 | ||||
1843 | s = splnet()splraise(0x4); | |||
1844 | if (if_rxr_inuse(&sc_if->sk_cdata.sk_rx_ring)((&sc_if->sk_cdata.sk_rx_ring)->rxr_alive) == 0) { | |||
1845 | msk_fill_rx_ring(sc_if); | |||
1846 | SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,sk_win_write_2(sc_if->sk_softc, 0x0464 + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_cdata.sk_rx_prod) | |||
1847 | sc_if->sk_cdata.sk_rx_prod)sk_win_write_2(sc_if->sk_softc, 0x0464 + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_cdata.sk_rx_prod); | |||
1848 | } | |||
1849 | splx(s)spllower(s); | |||
1850 | } | |||
1851 | ||||
1852 | void | |||
1853 | msk_tick(void *xsc_if) | |||
1854 | { | |||
1855 | struct sk_if_softc *sc_if = xsc_if; | |||
1856 | struct mii_data *mii = &sc_if->sk_mii; | |||
1857 | int s; | |||
1858 | ||||
1859 | s = splnet()splraise(0x4); | |||
1860 | mii_tick(mii); | |||
1861 | splx(s)spllower(s); | |||
1862 | timeout_add_sec(&sc_if->sk_tick_ch, 1); | |||
1863 | } | |||
1864 | ||||
1865 | void | |||
1866 | msk_intr_yukon(struct sk_if_softc *sc_if) | |||
1867 | { | |||
1868 | u_int8_t status; | |||
1869 | ||||
1870 | status = SK_IF_READ_1(sc_if, 0, SK_GMAC_ISR)sk_win_read_1(sc_if->sk_softc, 0x0f08 + ((sc_if->sk_port * (0 + 1)) * 0x80)); | |||
1871 | /* RX overrun */ | |||
1872 | if ((status & SK_GMAC_INT_RX_OVER0x02) != 0) { | |||
1873 | SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST,sk_win_write_1(sc_if->sk_softc, 0x0C48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000020) | |||
1874 | SK_RFCTL_RX_FIFO_OVER)sk_win_write_1(sc_if->sk_softc, 0x0C48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000020); | |||
1875 | } | |||
1876 | /* TX underrun */ | |||
1877 | if ((status & SK_GMAC_INT_TX_UNDER0x08) != 0) { | |||
1878 | SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST,sk_win_write_1(sc_if->sk_softc, 0x0D48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000040) | |||
1879 | SK_TFCTL_TX_FIFO_UNDER)sk_win_write_1(sc_if->sk_softc, 0x0D48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000040); | |||
1880 | } | |||
1881 | ||||
1882 | DPRINTFN(2, ("msk_intr_yukon status=%#x\n", status)); | |||
1883 | } | |||
1884 | ||||
1885 | int | |||
1886 | msk_intr(void *xsc) | |||
1887 | { | |||
1888 | struct sk_softc *sc = xsc; | |||
1889 | struct sk_if_softc *sc_if0 = sc->sk_if[SK_PORT_A0]; | |||
| ||||
1890 | struct sk_if_softc *sc_if1 = sc->sk_if[SK_PORT_B1]; | |||
1891 | struct mbuf_list ml[2] = { | |||
1892 | MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 }, | |||
1893 | MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 }, | |||
1894 | }; | |||
1895 | struct ifnet *ifp0 = NULL((void *)0), *ifp1 = NULL((void *)0); | |||
1896 | int claimed = 0; | |||
1897 | u_int32_t status; | |||
1898 | uint64_t *ring = sc->sk_status_ring; | |||
1899 | uint64_t desc; | |||
1900 | ||||
1901 | status = CSR_READ_4(sc, SK_Y2_ISSR2)(((sc)->sk_btag)->read_4(((sc)->sk_bhandle), ((0x001C )))); | |||
1902 | if (status == 0xffffffff) | |||
1903 | return (0); | |||
1904 | if (status == 0) { | |||
1905 | CSR_WRITE_4(sc, SK_Y2_ICR, 2)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((0x002C )), ((2)))); | |||
1906 | return (0); | |||
1907 | } | |||
1908 | ||||
1909 | status = CSR_READ_4(sc, SK_ISR)(((sc)->sk_btag)->read_4(((sc)->sk_bhandle), ((0x0008 )))); | |||
1910 | ||||
1911 | if (sc_if0 != NULL((void *)0)) | |||
1912 | ifp0 = &sc_if0->arpcom.ac_if; | |||
1913 | if (sc_if1 != NULL((void *)0)) | |||
1914 | ifp1 = &sc_if1->arpcom.ac_if; | |||
1915 | ||||
1916 | if (sc_if0
| |||
1917 | (ifp0->if_flags & IFF_RUNNING0x40)) { | |||
1918 | msk_intr_yukon(sc_if0); | |||
1919 | } | |||
1920 | ||||
1921 | if (sc_if1
| |||
1922 | (ifp1->if_flags & IFF_RUNNING0x40)) { | |||
1923 | msk_intr_yukon(sc_if1); | |||
1924 | } | |||
1925 | ||||
1926 | MSK_CDSTSYNC(sc, sc->sk_status_idx,do { (*((sc)->sc_dmatag)->_dmamap_sync)(((sc)->sc_dmatag ), ((sc)->sk_status_map), ((((sc->sk_status_idx)) * sizeof (uint64_t))), (sizeof(uint64_t)), ((0x02|0x08))); } while ( 0 ) | |||
1927 | BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)do { (*((sc)->sc_dmatag)->_dmamap_sync)(((sc)->sc_dmatag ), ((sc)->sk_status_map), ((((sc->sk_status_idx)) * sizeof (uint64_t))), (sizeof(uint64_t)), ((0x02|0x08))); } while ( 0 ); | |||
1928 | ||||
1929 | while (MSK_STATUS_OWN(desc = lemtoh64(&ring[sc->sk_status_idx]))(((desc = ((__uint64_t)(*(__uint64_t *)(&ring[sc->sk_status_idx ])))) >> 63) & 0x1)) { | |||
1930 | unsigned int opcode, port; | |||
1931 | ||||
1932 | ring[sc->sk_status_idx] = htole64(0)((__uint64_t)(0)); /* clear ownership */ | |||
1933 | ||||
1934 | opcode = MSK_STATUS_OPCODE(desc)(((desc) >> 56) & 0x7f); | |||
1935 | switch (opcode) { | |||
1936 | case MSK_STATUS_OPCODE_RXSTAT0x60: | |||
1937 | port = MSK_STATUS_RXSTAT_PORT(desc)(((desc) >> 48) & 0x1); | |||
1938 | msk_rxeof(sc->sk_if[port], &ml[port], | |||
1939 | MSK_STATUS_RXSTAT_LEN(desc)(((desc) >> 32) & 0xffff), | |||
1940 | MSK_STATUS_RXSTAT_STATUS(desc)(((desc) >> 0) & 0xffffffff)); | |||
1941 | break; | |||
1942 | case SK_Y2_STOPC_TXSTAT0x68: | |||
1943 | if (sc_if0) { | |||
1944 | msk_txeof(sc_if0, | |||
1945 | MSK_STATUS_TXIDX_PORTA(desc)(((desc) >> 0) & 0xfff)); | |||
1946 | } | |||
1947 | if (sc_if1) { | |||
1948 | msk_txeof(sc_if1, | |||
1949 | MSK_STATUS_TXIDX_PORTB(desc)(((desc) >> 24) & 0xfff)); | |||
1950 | } | |||
1951 | break; | |||
1952 | default: | |||
1953 | printf("opcode=0x%x\n", opcode); | |||
1954 | break; | |||
1955 | } | |||
1956 | ||||
1957 | SK_INC(sc->sk_status_idx, MSK_STATUS_RING_CNT)(sc->sk_status_idx) = (sc->sk_status_idx + 1) % 2048; | |||
1958 | } | |||
1959 | ||||
1960 | MSK_CDSTSYNC(sc, sc->sk_status_idx,do { (*((sc)->sc_dmatag)->_dmamap_sync)(((sc)->sc_dmatag ), ((sc)->sk_status_map), ((((sc->sk_status_idx)) * sizeof (uint64_t))), (sizeof(uint64_t)), ((0x02|0x08))); } while ( 0 ) | |||
1961 | BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)do { (*((sc)->sc_dmatag)->_dmamap_sync)(((sc)->sc_dmatag ), ((sc)->sk_status_map), ((((sc->sk_status_idx)) * sizeof (uint64_t))), (sizeof(uint64_t)), ((0x02|0x08))); } while ( 0 ); | |||
1962 | ||||
1963 | if (status & SK_Y2_IMR_BMU0x40000000) { | |||
1964 | CSR_WRITE_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_IRQ_CLEAR)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((0x0e80 )), ((0x00000010)))); | |||
1965 | claimed = 1; | |||
1966 | } | |||
1967 | ||||
1968 | CSR_WRITE_4(sc, SK_Y2_ICR, 2)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((0x002C )), ((2)))); | |||
1969 | ||||
1970 | if (!ml_empty(&ml[0])((&ml[0])->ml_len == 0)) { | |||
1971 | if (ifiq_input(&ifp0->if_rcv, &ml[0])) | |||
1972 | if_rxr_livelocked(&sc_if0->sk_cdata.sk_rx_ring); | |||
1973 | msk_fill_rx_ring(sc_if0); | |||
1974 | SK_IF_WRITE_2(sc_if0, 0, SK_RXQ1_Y2_PREF_PUTIDX,sk_win_write_2(sc_if0->sk_softc, 0x0464 + ((sc_if0->sk_port * (0 + 1)) * 0x80), sc_if0->sk_cdata.sk_rx_prod) | |||
| ||||
1975 | sc_if0->sk_cdata.sk_rx_prod)sk_win_write_2(sc_if0->sk_softc, 0x0464 + ((sc_if0->sk_port * (0 + 1)) * 0x80), sc_if0->sk_cdata.sk_rx_prod); | |||
1976 | } | |||
1977 | if (!ml_empty(&ml[1])((&ml[1])->ml_len == 0)) { | |||
1978 | if (ifiq_input(&ifp1->if_rcv, &ml[1])) | |||
1979 | if_rxr_livelocked(&sc_if1->sk_cdata.sk_rx_ring); | |||
1980 | msk_fill_rx_ring(sc_if1); | |||
1981 | SK_IF_WRITE_2(sc_if1, 0, SK_RXQ1_Y2_PREF_PUTIDX,sk_win_write_2(sc_if1->sk_softc, 0x0464 + ((sc_if1->sk_port * (0 + 1)) * 0x80), sc_if1->sk_cdata.sk_rx_prod) | |||
1982 | sc_if1->sk_cdata.sk_rx_prod)sk_win_write_2(sc_if1->sk_softc, 0x0464 + ((sc_if1->sk_port * (0 + 1)) * 0x80), sc_if1->sk_cdata.sk_rx_prod); | |||
1983 | } | |||
1984 | ||||
1985 | return (claimed); | |||
1986 | } | |||
1987 | ||||
1988 | void | |||
1989 | msk_init_yukon(struct sk_if_softc *sc_if) | |||
1990 | { | |||
1991 | u_int32_t v; | |||
1992 | u_int16_t reg; | |||
1993 | struct sk_softc *sc; | |||
1994 | int i; | |||
1995 | ||||
1996 | sc = sc_if->sk_softc; | |||
1997 | ||||
1998 | DPRINTFN(2, ("msk_init_yukon: start: sk_csr=%#x\n", | |||
1999 | CSR_READ_4(sc_if->sk_softc, SK_CSR))); | |||
2000 | ||||
2001 | DPRINTFN(6, ("msk_init_yukon: 1\n")); | |||
2002 | ||||
2003 | DPRINTFN(3, ("msk_init_yukon: gmac_ctrl=%#x\n", | |||
2004 | SK_IF_READ_4(sc_if, 0, SK_GMAC_CTRL))); | |||
2005 | ||||
2006 | DPRINTFN(6, ("msk_init_yukon: 3\n")); | |||
2007 | ||||
2008 | /* unused read of the interrupt source register */ | |||
2009 | DPRINTFN(6, ("msk_init_yukon: 4\n")); | |||
2010 | SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR)sk_win_read_2(sc_if->sk_softc, 0x0f08 + ((sc_if->sk_port * (0 + 1)) * 0x80)); | |||
2011 | ||||
2012 | DPRINTFN(6, ("msk_init_yukon: 4a\n")); | |||
2013 | reg = SK_YU_READ_2(sc_if, YUKON_PAR)sk_win_read_2((sc_if)->sk_softc, (((0x0088)) + 0x2800 + (( ((sc_if))->sk_port) * (0x3800 - 0x2800)))); | |||
2014 | DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg)); | |||
2015 | ||||
2016 | /* MIB Counter Clear Mode set */ | |||
2017 | reg |= YU_PAR_MIB_CLR0x0020; | |||
2018 | DPRINTFN(6, ("msk_init_yukon: YUKON_PAR=%#x\n", reg)); | |||
2019 | DPRINTFN(6, ("msk_init_yukon: 4b\n")); | |||
2020 | SK_YU_WRITE_2(sc_if, YUKON_PAR, reg)sk_win_write_2((sc_if)->sk_softc, (((0x0088)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (reg)); | |||
2021 | ||||
2022 | /* MIB Counter Clear Mode clear */ | |||
2023 | DPRINTFN(6, ("msk_init_yukon: 5\n")); | |||
2024 | reg &= ~YU_PAR_MIB_CLR0x0020; | |||
2025 | SK_YU_WRITE_2(sc_if, YUKON_PAR, reg)sk_win_write_2((sc_if)->sk_softc, (((0x0088)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (reg)); | |||
2026 | ||||
2027 | /* receive control reg */ | |||
2028 | DPRINTFN(6, ("msk_init_yukon: 7\n")); | |||
2029 | SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR)sk_win_write_2((sc_if)->sk_softc, (((0x000c)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (0x2000)); | |||
2030 | ||||
2031 | /* transmit parameter register */ | |||
2032 | DPRINTFN(6, ("msk_init_yukon: 8\n")); | |||
2033 | SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |sk_win_write_2((sc_if)->sk_softc, (((0x0014)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((((0x3) & 0x3) << 14) | (((0xb) & 0x1f) << 9) | (((0x1a ) & 0x1f) << 4))) | |||
2034 | YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) )sk_win_write_2((sc_if)->sk_softc, (((0x0014)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), ((((0x3) & 0x3) << 14) | (((0xb) & 0x1f) << 9) | (((0x1a ) & 0x1f) << 4))); | |||
2035 | ||||
2036 | /* serial mode register */ | |||
2037 | DPRINTFN(6, ("msk_init_yukon: 9\n")); | |||
2038 | reg = YU_SMR_DATA_BLIND(0x1c)(((0x1c) & 0x1f) << 11) | | |||
2039 | YU_SMR_MFL_VLAN0x0200 | | |||
2040 | YU_SMR_IPG_DATA(0x1e)((0x1e) & 0x1f); | |||
2041 | ||||
2042 | if (sc->sk_type != SK_YUKON_FE0xB7 && | |||
2043 | sc->sk_type != SK_YUKON_FE_P0xB8) | |||
2044 | reg |= YU_SMR_MFL_JUMBO0x0100; | |||
2045 | ||||
2046 | SK_YU_WRITE_2(sc_if, YUKON_SMR, reg)sk_win_write_2((sc_if)->sk_softc, (((0x0018)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (reg)); | |||
2047 | ||||
2048 | DPRINTFN(6, ("msk_init_yukon: 10\n")); | |||
2049 | /* Setup Yukon's address */ | |||
2050 | for (i = 0; i < 3; i++) { | |||
2051 | /* Write Source Address 1 (unicast filter) */ | |||
2052 | SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4,sk_win_write_2((sc_if)->sk_softc, (((0x001c + i * 4)) + 0x2800 + ((((sc_if))->sk_port) * (0x3800 - 0x2800))), (sc_if-> arpcom.ac_enaddr[i * 2] | sc_if->arpcom.ac_enaddr[i * 2 + 1 ] << 8)) | |||
2053 | sc_if->arpcom.ac_enaddr[i * 2] |sk_win_write_2((sc_if)->sk_softc, (((0x001c + i * 4)) + 0x2800 + ((((sc_if))->sk_port) * (0x3800 - 0x2800))), (sc_if-> arpcom.ac_enaddr[i * 2] | sc_if->arpcom.ac_enaddr[i * 2 + 1 ] << 8)) | |||
2054 | sc_if->arpcom.ac_enaddr[i * 2 + 1] << 8)sk_win_write_2((sc_if)->sk_softc, (((0x001c + i * 4)) + 0x2800 + ((((sc_if))->sk_port) * (0x3800 - 0x2800))), (sc_if-> arpcom.ac_enaddr[i * 2] | sc_if->arpcom.ac_enaddr[i * 2 + 1 ] << 8)); | |||
2055 | } | |||
2056 | ||||
2057 | for (i = 0; i < 3; i++) { | |||
2058 | reg = sk_win_read_2(sc_if->sk_softc, | |||
2059 | SK_MAC1_00x0108 + i * 2 + sc_if->sk_port * 8); | |||
2060 | SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg)sk_win_write_2((sc_if)->sk_softc, (((0x0028 + i * 4)) + 0x2800 + ((((sc_if))->sk_port) * (0x3800 - 0x2800))), (reg)); | |||
2061 | } | |||
2062 | ||||
2063 | /* Program promiscuous mode and multicast filters */ | |||
2064 | DPRINTFN(6, ("msk_init_yukon: 11\n")); | |||
2065 | msk_iff(sc_if); | |||
2066 | ||||
2067 | /* enable interrupt mask for counter overflows */ | |||
2068 | DPRINTFN(6, ("msk_init_yukon: 12\n")); | |||
2069 | SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0)sk_win_write_2((sc_if)->sk_softc, (((0x0050)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (0)); | |||
2070 | SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0)sk_win_write_2((sc_if)->sk_softc, (((0x0054)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (0)); | |||
2071 | SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0)sk_win_write_2((sc_if)->sk_softc, (((0x0058)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (0)); | |||
2072 | ||||
2073 | /* Configure RX MAC FIFO Flush Mask */ | |||
2074 | v = YU_RXSTAT_FOFL0x00000001 | YU_RXSTAT_CRCERR0x00000002 | YU_RXSTAT_MIIERR0x00000020 | | |||
2075 | YU_RXSTAT_BADFC0x00000040 | YU_RXSTAT_GOODFC0x00000080 | YU_RXSTAT_RUNT0x00000800 | | |||
2076 | YU_RXSTAT_JABBER0x00001000; | |||
2077 | SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_MASK, v)sk_win_write_2(sc_if->sk_softc, 0x0C4C + ((sc_if->sk_port * (0 + 1)) * 0x80), v); | |||
2078 | ||||
2079 | /* Configure RX MAC FIFO */ | |||
2080 | SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR)sk_win_write_1(sc_if->sk_softc, 0x0C48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000002); | |||
2081 | SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_OPERATION_ON |sk_win_write_2(sc_if->sk_softc, 0x0C48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000008 | 0x00000080) | |||
2082 | SK_RFCTL_FIFO_FLUSH_ON)sk_win_write_2(sc_if->sk_softc, 0x0C48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000008 | 0x00000080); | |||
2083 | ||||
2084 | /* Increase flush threshold to 64 bytes */ | |||
2085 | SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_THRESHOLD,sk_win_write_2(sc_if->sk_softc, 0x0C50 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x0a + 1) | |||
2086 | SK_RFCTL_FIFO_THRESHOLD + 1)sk_win_write_2(sc_if->sk_softc, 0x0C50 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x0a + 1); | |||
2087 | ||||
2088 | /* Configure TX MAC FIFO */ | |||
2089 | SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR)sk_win_write_1(sc_if->sk_softc, 0x0D48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000002); | |||
2090 | SK_IF_WRITE_2(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON)sk_win_write_2(sc_if->sk_softc, 0x0D48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000008); | |||
2091 | ||||
2092 | #if 1 | |||
2093 | SK_YU_WRITE_2(sc_if, YUKON_GPCR, YU_GPCR_TXEN | YU_GPCR_RXEN)sk_win_write_2((sc_if)->sk_softc, (((0x0004)) + 0x2800 + ( (((sc_if))->sk_port) * (0x3800 - 0x2800))), (0x1000 | 0x0800 )); | |||
2094 | #endif | |||
2095 | DPRINTFN(6, ("msk_init_yukon: end\n")); | |||
2096 | } | |||
2097 | ||||
2098 | /* | |||
2099 | * Note that to properly initialize any part of the GEnesis chip, | |||
2100 | * you first have to take it out of reset mode. | |||
2101 | */ | |||
2102 | void | |||
2103 | msk_init(void *xsc_if) | |||
2104 | { | |||
2105 | struct sk_if_softc *sc_if = xsc_if; | |||
2106 | struct sk_softc *sc = sc_if->sk_softc; | |||
2107 | struct ifnet *ifp = &sc_if->arpcom.ac_if; | |||
2108 | struct mii_data *mii = &sc_if->sk_mii; | |||
2109 | int s; | |||
2110 | ||||
2111 | DPRINTFN(2, ("msk_init\n")); | |||
2112 | ||||
2113 | s = splnet()splraise(0x4); | |||
2114 | ||||
2115 | /* Cancel pending I/O and free all RX/TX buffers. */ | |||
2116 | msk_stop(sc_if, 0); | |||
2117 | ||||
2118 | /* Configure I2C registers */ | |||
2119 | ||||
2120 | /* Configure XMAC(s) */ | |||
2121 | msk_init_yukon(sc_if); | |||
2122 | mii_mediachg(mii); | |||
2123 | ||||
2124 | /* Configure transmit arbiter(s) */ | |||
2125 | SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_ON)sk_win_write_1(sc_if->sk_softc, 0x0210 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x02); | |||
2126 | #if 0 | |||
2127 | SK_TXARCTL_ON0x02|SK_TXARCTL_FSYNC_ON0x80); | |||
2128 | #endif | |||
2129 | ||||
2130 | /* Configure RAMbuffers */ | |||
2131 | SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET)sk_win_write_4(sc_if->sk_softc, 0x0828 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000002); | |||
2132 | SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart)sk_win_write_4(sc_if->sk_softc, 0x0800 + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_rx_ramstart); | |||
2133 | SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart)sk_win_write_4(sc_if->sk_softc, 0x0808 + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_rx_ramstart); | |||
2134 | SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart)sk_win_write_4(sc_if->sk_softc, 0x080C + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_rx_ramstart); | |||
2135 | SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend)sk_win_write_4(sc_if->sk_softc, 0x0804 + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_rx_ramend); | |||
2136 | SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON)sk_win_write_4(sc_if->sk_softc, 0x0828 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000008); | |||
2137 | ||||
2138 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_UNRESET)sk_win_write_4(sc_if->sk_softc, 0x0AA8 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000002); | |||
2139 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_STORENFWD_ON)sk_win_write_4(sc_if->sk_softc, 0x0AA8 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000020); | |||
2140 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_START, sc_if->sk_tx_ramstart)sk_win_write_4(sc_if->sk_softc, 0x0A80 + ((sc_if->sk_port * (1 + 1)) * 0x80), sc_if->sk_tx_ramstart); | |||
2141 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_WR_PTR, sc_if->sk_tx_ramstart)sk_win_write_4(sc_if->sk_softc, 0x0A88 + ((sc_if->sk_port * (1 + 1)) * 0x80), sc_if->sk_tx_ramstart); | |||
2142 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_RD_PTR, sc_if->sk_tx_ramstart)sk_win_write_4(sc_if->sk_softc, 0x0A8C + ((sc_if->sk_port * (1 + 1)) * 0x80), sc_if->sk_tx_ramstart); | |||
2143 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_END, sc_if->sk_tx_ramend)sk_win_write_4(sc_if->sk_softc, 0x0A84 + ((sc_if->sk_port * (1 + 1)) * 0x80), sc_if->sk_tx_ramend); | |||
2144 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_ON)sk_win_write_4(sc_if->sk_softc, 0x0AA8 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000008); | |||
2145 | ||||
2146 | /* Configure BMUs */ | |||
2147 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000016)sk_win_write_4(sc_if->sk_softc, 0x0434 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000016); | |||
2148 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000d28)sk_win_write_4(sc_if->sk_softc, 0x0434 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000d28); | |||
2149 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, 0x00000080)sk_win_write_4(sc_if->sk_softc, 0x0434 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000080); | |||
2150 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_WATERMARK, 0x00000600)sk_win_write_4(sc_if->sk_softc, 0x0438 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000600); | |||
2151 | ||||
2152 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000016)sk_win_write_4(sc_if->sk_softc, 0x06B4 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000016); | |||
2153 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000d28)sk_win_write_4(sc_if->sk_softc, 0x06B4 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000d28); | |||
2154 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, 0x00000080)sk_win_write_4(sc_if->sk_softc, 0x06B4 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000080); | |||
2155 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_WATERMARK, 0x00000600)sk_win_write_4(sc_if->sk_softc, 0x06B8 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000600); | |||
2156 | ||||
2157 | /* Make sure the sync transmit queue is disabled. */ | |||
2158 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET)sk_win_write_4(sc_if->sk_softc, 0x0A28 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000001); | |||
2159 | ||||
2160 | /* Init descriptors */ | |||
2161 | if (msk_init_rx_ring(sc_if) == ENOBUFS55) { | |||
2162 | printf("%s: initialization failed: no " | |||
2163 | "memory for rx buffers\n", sc_if->sk_dev.dv_xname); | |||
2164 | msk_stop(sc_if, 0); | |||
2165 | splx(s)spllower(s); | |||
2166 | return; | |||
2167 | } | |||
2168 | ||||
2169 | if (msk_init_tx_ring(sc_if) == ENOBUFS55) { | |||
2170 | printf("%s: initialization failed: no " | |||
2171 | "memory for tx buffers\n", sc_if->sk_dev.dv_xname); | |||
2172 | msk_stop(sc_if, 0); | |||
2173 | splx(s)spllower(s); | |||
2174 | return; | |||
2175 | } | |||
2176 | ||||
2177 | /* Initialize prefetch engine. */ | |||
2178 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001)sk_win_write_4(sc_if->sk_softc, 0x0450 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000001); | |||
2179 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000002)sk_win_write_4(sc_if->sk_softc, 0x0450 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000002); | |||
2180 | SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_LIDX, MSK_RX_RING_CNT - 1)sk_win_write_2(sc_if->sk_softc, 0x0454 + ((sc_if->sk_port * (0 + 1)) * 0x80), 512 - 1); | |||
2181 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRLO,sk_win_write_4(sc_if->sk_softc, 0x0458 + ((sc_if->sk_port * (0 + 1)) * 0x80), ((sc_if)->sk_ring_map->dm_segs[0]. ds_addr + __builtin_offsetof(struct msk_ring_data, sk_rx_ring [(0)]))) | |||
2182 | MSK_RX_RING_ADDR(sc_if, 0))sk_win_write_4(sc_if->sk_softc, 0x0458 + ((sc_if->sk_port * (0 + 1)) * 0x80), ((sc_if)->sk_ring_map->dm_segs[0]. ds_addr + __builtin_offsetof(struct msk_ring_data, sk_rx_ring [(0)]))); | |||
2183 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_ADDRHI,sk_win_write_4(sc_if->sk_softc, 0x045C + ((sc_if->sk_port * (0 + 1)) * 0x80), (u_int64_t)((sc_if)->sk_ring_map-> dm_segs[0].ds_addr + __builtin_offsetof(struct msk_ring_data, sk_rx_ring[(0)])) >> 32) | |||
2184 | (u_int64_t)MSK_RX_RING_ADDR(sc_if, 0) >> 32)sk_win_write_4(sc_if->sk_softc, 0x045C + ((sc_if->sk_port * (0 + 1)) * 0x80), (u_int64_t)((sc_if)->sk_ring_map-> dm_segs[0].ds_addr + __builtin_offsetof(struct msk_ring_data, sk_rx_ring[(0)])) >> 32); | |||
2185 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000008)sk_win_write_4(sc_if->sk_softc, 0x0450 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000008); | |||
2186 | SK_IF_READ_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR)sk_win_read_4(sc_if->sk_softc, 0x0450 + ((sc_if->sk_port * (0 + 1)) * 0x80)); | |||
2187 | ||||
2188 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001)sk_win_write_4(sc_if->sk_softc, 0x06D0 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000001); | |||
2189 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000002)sk_win_write_4(sc_if->sk_softc, 0x06D0 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000002); | |||
2190 | SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_LIDX, MSK_TX_RING_CNT - 1)sk_win_write_2(sc_if->sk_softc, 0x06D4 + ((sc_if->sk_port * (1 + 1)) * 0x80), 512 - 1); | |||
2191 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRLO,sk_win_write_4(sc_if->sk_softc, 0x06D8 + ((sc_if->sk_port * (1 + 1)) * 0x80), ((sc_if)->sk_ring_map->dm_segs[0]. ds_addr + __builtin_offsetof(struct msk_ring_data, sk_tx_ring [(0)]))) | |||
2192 | MSK_TX_RING_ADDR(sc_if, 0))sk_win_write_4(sc_if->sk_softc, 0x06D8 + ((sc_if->sk_port * (1 + 1)) * 0x80), ((sc_if)->sk_ring_map->dm_segs[0]. ds_addr + __builtin_offsetof(struct msk_ring_data, sk_tx_ring [(0)]))); | |||
2193 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_ADDRHI,sk_win_write_4(sc_if->sk_softc, 0x06DC + ((sc_if->sk_port * (1 + 1)) * 0x80), (u_int64_t)((sc_if)->sk_ring_map-> dm_segs[0].ds_addr + __builtin_offsetof(struct msk_ring_data, sk_tx_ring[(0)])) >> 32) | |||
2194 | (u_int64_t)MSK_TX_RING_ADDR(sc_if, 0) >> 32)sk_win_write_4(sc_if->sk_softc, 0x06DC + ((sc_if->sk_port * (1 + 1)) * 0x80), (u_int64_t)((sc_if)->sk_ring_map-> dm_segs[0].ds_addr + __builtin_offsetof(struct msk_ring_data, sk_tx_ring[(0)])) >> 32); | |||
2195 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000008)sk_win_write_4(sc_if->sk_softc, 0x06D0 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000008); | |||
2196 | SK_IF_READ_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR)sk_win_read_4(sc_if->sk_softc, 0x06D0 + ((sc_if->sk_port * (1 + 1)) * 0x80)); | |||
2197 | ||||
2198 | SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,sk_win_write_2(sc_if->sk_softc, 0x0464 + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_cdata.sk_rx_prod) | |||
2199 | sc_if->sk_cdata.sk_rx_prod)sk_win_write_2(sc_if->sk_softc, 0x0464 + ((sc_if->sk_port * (0 + 1)) * 0x80), sc_if->sk_cdata.sk_rx_prod); | |||
2200 | ||||
2201 | /* | |||
2202 | * tell the chip the tx ring is empty for now. the first | |||
2203 | * msk_start will end up posting the ADDR64 tx descriptor | |||
2204 | * that resets the high address. | |||
2205 | */ | |||
2206 | SK_IF_WRITE_2(sc_if, 1, SK_TXQA1_Y2_PREF_PUTIDX, 0)sk_win_write_2(sc_if->sk_softc, 0x06E4 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0); | |||
2207 | ||||
2208 | /* Configure interrupt handling */ | |||
2209 | if (sc_if->sk_port == SK_PORT_A0) | |||
2210 | sc->sk_intrmask |= SK_Y2_INTRS1(0x00000004|0x00000001 |0x00000008|0x00000010); | |||
2211 | else | |||
2212 | sc->sk_intrmask |= SK_Y2_INTRS2(0x00000400|0x00000100 |0x00000800|0x00001000); | |||
2213 | sc->sk_intrmask |= SK_Y2_IMR_BMU0x40000000; | |||
2214 | CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((0x000C )), ((sc->sk_intrmask)))); | |||
2215 | ||||
2216 | ifp->if_flags |= IFF_RUNNING0x40; | |||
2217 | ifq_clr_oactive(&ifp->if_snd); | |||
2218 | ||||
2219 | timeout_add_sec(&sc_if->sk_tick_ch, 1); | |||
2220 | ||||
2221 | splx(s)spllower(s); | |||
2222 | } | |||
2223 | ||||
2224 | void | |||
2225 | msk_stop(struct sk_if_softc *sc_if, int softonly) | |||
2226 | { | |||
2227 | struct sk_softc *sc = sc_if->sk_softc; | |||
2228 | struct ifnet *ifp = &sc_if->arpcom.ac_if; | |||
2229 | struct mbuf *m; | |||
2230 | bus_dmamap_t map; | |||
2231 | int i; | |||
2232 | ||||
2233 | DPRINTFN(2, ("msk_stop\n")); | |||
2234 | ||||
2235 | timeout_del(&sc_if->sk_tick_ch); | |||
2236 | timeout_del(&sc_if->sk_tick_rx); | |||
2237 | ||||
2238 | ifp->if_flags &= ~IFF_RUNNING0x40; | |||
2239 | ifq_clr_oactive(&ifp->if_snd); | |||
2240 | ||||
2241 | /* Stop transfer of Tx descriptors */ | |||
2242 | ||||
2243 | /* Stop transfer of Rx descriptors */ | |||
2244 | ||||
2245 | if (!softonly) { | |||
2246 | /* Turn off various components of this interface. */ | |||
2247 | SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET)sk_win_write_1(sc_if->sk_softc, 0x0C48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000001); | |||
2248 | SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET)sk_win_write_1(sc_if->sk_softc, 0x0D48 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000001); | |||
2249 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE)sk_win_write_4(sc_if->sk_softc, 0x0434 + ((sc_if->sk_port * (0 + 1)) * 0x80), (0x00000100|0x00000400| 0x00001000|0x00004000 | 0x00010000|0x00040000| 0x00100000)); | |||
2250 | SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF)sk_win_write_4(sc_if->sk_softc, 0x0828 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000001|0x00000004); | |||
2251 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE)sk_win_write_4(sc_if->sk_softc, 0x06B4 + ((sc_if->sk_port * (1 + 1)) * 0x80), (0x00000100|0x00000400| 0x00001000|0x00004000 | 0x00010000|0x00040000| 0x00100000|0x00000040)); | |||
2252 | SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF)sk_win_write_4(sc_if->sk_softc, 0x0AA8 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000001|0x00000004); | |||
2253 | SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF)sk_win_write_1(sc_if->sk_softc, 0x0210 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x01); | |||
2254 | SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP)sk_win_write_1(sc_if->sk_softc, 0x0C28 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x0002); | |||
2255 | SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP)sk_win_write_1(sc_if->sk_softc, 0x0D28 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x0002); | |||
2256 | SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF)sk_win_write_1(sc_if->sk_softc, 0x0C3C + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x0001); | |||
2257 | SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF)sk_win_write_1(sc_if->sk_softc, 0x0C3C + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x0004); | |||
2258 | ||||
2259 | SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001)sk_win_write_4(sc_if->sk_softc, 0x0450 + ((sc_if->sk_port * (0 + 1)) * 0x80), 0x00000001); | |||
2260 | SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001)sk_win_write_4(sc_if->sk_softc, 0x06D0 + ((sc_if->sk_port * (1 + 1)) * 0x80), 0x00000001); | |||
2261 | ||||
2262 | /* Disable interrupts */ | |||
2263 | if (sc_if->sk_port == SK_PORT_A0) | |||
2264 | sc->sk_intrmask &= ~SK_Y2_INTRS1(0x00000004|0x00000001 |0x00000008|0x00000010); | |||
2265 | else | |||
2266 | sc->sk_intrmask &= ~SK_Y2_INTRS2(0x00000400|0x00000100 |0x00000800|0x00001000); | |||
2267 | CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask)(((sc)->sk_btag)->write_4(((sc)->sk_bhandle), ((0x000C )), ((sc->sk_intrmask)))); | |||
2268 | } | |||
2269 | ||||
2270 | /* Free RX and TX mbufs still in the queues. */ | |||
2271 | for (i = 0; i < MSK_RX_RING_CNT512; i++) { | |||
2272 | m = sc_if->sk_cdata.sk_rx_mbuf[i]; | |||
2273 | if (m == NULL((void *)0)) | |||
2274 | continue; | |||
2275 | ||||
2276 | map = sc_if->sk_cdata.sk_rx_maps[i]; | |||
2277 | bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x02)) | |||
2278 | BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x02)); | |||
2279 | bus_dmamap_unload(sc->sc_dmatag, map)(*(sc->sc_dmatag)->_dmamap_unload)((sc->sc_dmatag), ( map)); | |||
2280 | ||||
2281 | m_freem(m); | |||
2282 | ||||
2283 | sc_if->sk_cdata.sk_rx_mbuf[i] = NULL((void *)0); | |||
2284 | } | |||
2285 | ||||
2286 | sc_if->sk_cdata.sk_rx_prod = 0; | |||
2287 | sc_if->sk_cdata.sk_rx_cons = 0; | |||
2288 | ||||
2289 | for (i = 0; i < MSK_TX_RING_CNT512; i++) { | |||
2290 | m = sc_if->sk_cdata.sk_tx_mbuf[i]; | |||
2291 | if (m == NULL((void *)0)) | |||
2292 | continue; | |||
2293 | ||||
2294 | map = sc_if->sk_cdata.sk_tx_maps[i]; | |||
2295 | bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x02)) | |||
2296 | BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (map ), (0), (map->dm_mapsize), (0x02)); | |||
2297 | bus_dmamap_unload(sc->sc_dmatag, map)(*(sc->sc_dmatag)->_dmamap_unload)((sc->sc_dmatag), ( map)); | |||
2298 | ||||
2299 | m_freem(m); | |||
2300 | ||||
2301 | sc_if->sk_cdata.sk_tx_mbuf[i] = NULL((void *)0); | |||
2302 | } | |||
2303 | } | |||
2304 | ||||
2305 | const struct cfattach mskc_ca = { | |||
2306 | sizeof(struct sk_softc), mskc_probe, mskc_attach, mskc_detach, | |||
2307 | mskc_activate | |||
2308 | }; | |||
2309 | ||||
2310 | struct cfdriver mskc_cd = { | |||
2311 | NULL((void *)0), "mskc", DV_DULL | |||
2312 | }; | |||
2313 | ||||
2314 | const struct cfattach msk_ca = { | |||
2315 | sizeof(struct sk_if_softc), msk_probe, msk_attach, msk_detach, | |||
2316 | msk_activate | |||
2317 | }; | |||
2318 | ||||
2319 | struct cfdriver msk_cd = { | |||
2320 | NULL((void *)0), "msk", DV_IFNET | |||
2321 | }; | |||
2322 | ||||
2323 | #if NKSTAT1 > 0 | |||
2324 | static uint32_t | |||
2325 | msk_mib_read32(struct sk_if_softc *sc_if, uint32_t r) | |||
2326 | { | |||
2327 | uint16_t hi, lo, xx; | |||
2328 | ||||
2329 | hi = SK_YU_READ_2(sc_if, r + 4)sk_win_read_2((sc_if)->sk_softc, (((r + 4)) + 0x2800 + ((( (sc_if))->sk_port) * (0x3800 - 0x2800)))); | |||
2330 | for (;;) { | |||
2331 | /* XXX barriers? */ | |||
2332 | lo = SK_YU_READ_2(sc_if, r)sk_win_read_2((sc_if)->sk_softc, (((r)) + 0x2800 + ((((sc_if ))->sk_port) * (0x3800 - 0x2800)))); | |||
2333 | xx = SK_YU_READ_2(sc_if, r + 4)sk_win_read_2((sc_if)->sk_softc, (((r + 4)) + 0x2800 + ((( (sc_if))->sk_port) * (0x3800 - 0x2800)))); | |||
2334 | ||||
2335 | if (hi == xx) | |||
2336 | break; | |||
2337 | ||||
2338 | hi = xx; | |||
2339 | } | |||
2340 | ||||
2341 | return (((uint32_t)hi << 16) | (uint32_t) lo); | |||
2342 | } | |||
2343 | ||||
2344 | static uint64_t | |||
2345 | msk_mib_read64(struct sk_if_softc *sc_if, uint32_t r) | |||
2346 | { | |||
2347 | uint32_t hi, lo, xx; | |||
2348 | ||||
2349 | hi = msk_mib_read32(sc_if, r + 8); | |||
2350 | for (;;) { | |||
2351 | lo = msk_mib_read32(sc_if, r); | |||
2352 | xx = msk_mib_read32(sc_if, r + 8); | |||
2353 | ||||
2354 | if (hi == xx) | |||
2355 | break; | |||
2356 | ||||
2357 | hi = xx; | |||
2358 | } | |||
2359 | ||||
2360 | return (((uint64_t)hi << 32) | (uint64_t)lo); | |||
2361 | } | |||
2362 | ||||
2363 | void | |||
2364 | msk_kstat_attach(struct sk_if_softc *sc_if) | |||
2365 | { | |||
2366 | struct kstat *ks; | |||
2367 | struct kstat_kv *kvs; | |||
2368 | struct msk_kstat *mks; | |||
2369 | size_t i; | |||
2370 | ||||
2371 | ks = kstat_create(sc_if->sk_dev.dv_xname, 0, "msk-mib", 0, | |||
2372 | KSTAT_T_KV1, 0); | |||
2373 | if (ks == NULL((void *)0)) { | |||
2374 | /* oh well */ | |||
2375 | return; | |||
2376 | } | |||
2377 | ||||
2378 | mks = malloc(sizeof(*mks), M_DEVBUF2, M_WAITOK0x0001); | |||
2379 | rw_init(&mks->lock, "mskstat")_rw_init_flags(&mks->lock, "mskstat", 0, ((void *)0)); | |||
2380 | mks->ks = ks; | |||
2381 | ||||
2382 | kvs = mallocarray(nitems(msk_mib)(sizeof((msk_mib)) / sizeof((msk_mib)[0])), sizeof(*kvs), | |||
2383 | M_DEVBUF2, M_WAITOK0x0001|M_ZERO0x0008); | |||
2384 | for (i = 0; i < nitems(msk_mib)(sizeof((msk_mib)) / sizeof((msk_mib)[0])); i++) { | |||
2385 | const struct msk_mib *m = &msk_mib[i]; | |||
2386 | kstat_kv_unit_init(&kvs[i], m->name, m->type, m->unit); | |||
2387 | } | |||
2388 | ||||
2389 | ks->ks_softc = sc_if; | |||
2390 | ks->ks_data = kvs; | |||
2391 | ks->ks_datalen = nitems(msk_mib)(sizeof((msk_mib)) / sizeof((msk_mib)[0])) * sizeof(*kvs); | |||
2392 | ks->ks_read = msk_kstat_read; | |||
2393 | kstat_set_wlock(ks, &mks->lock); | |||
2394 | ||||
2395 | kstat_install(ks); | |||
2396 | ||||
2397 | sc_if->sk_kstat = mks; | |||
2398 | } | |||
2399 | ||||
2400 | void | |||
2401 | msk_kstat_detach(struct sk_if_softc *sc_if) | |||
2402 | { | |||
2403 | struct msk_kstat *mks = sc_if->sk_kstat; | |||
2404 | struct kstat_kv *kvs; | |||
2405 | size_t kvslen; | |||
2406 | ||||
2407 | if (mks == NULL((void *)0)) | |||
2408 | return; | |||
2409 | ||||
2410 | sc_if->sk_kstat = NULL((void *)0); | |||
2411 | ||||
2412 | kvs = mks->ks->ks_data; | |||
2413 | kvslen = mks->ks->ks_datalen; | |||
2414 | ||||
2415 | kstat_destroy(mks->ks); | |||
2416 | free(kvs, M_DEVBUF2, kvslen); | |||
2417 | free(mks, M_DEVBUF2, sizeof(*mks)); | |||
2418 | } | |||
2419 | ||||
2420 | int | |||
2421 | msk_kstat_read(struct kstat *ks) | |||
2422 | { | |||
2423 | struct sk_if_softc *sc_if = ks->ks_softc; | |||
2424 | struct kstat_kv *kvs = ks->ks_data; | |||
2425 | size_t i; | |||
2426 | ||||
2427 | nanouptime(&ks->ks_updated); | |||
2428 | ||||
2429 | for (i = 0; i < nitems(msk_mib)(sizeof((msk_mib)) / sizeof((msk_mib)[0])); i++) { | |||
2430 | const struct msk_mib *m = &msk_mib[i]; | |||
2431 | ||||
2432 | switch (m->type) { | |||
2433 | case KSTAT_KV_T_COUNTER32: | |||
2434 | kstat_kv_u32(&kvs[i])(&kvs[i])->kv_v.v_u32 = msk_mib_read32(sc_if, m->reg); | |||
2435 | break; | |||
2436 | case KSTAT_KV_T_COUNTER64: | |||
2437 | kstat_kv_u64(&kvs[i])(&kvs[i])->kv_v.v_u64 = msk_mib_read64(sc_if, m->reg); | |||
2438 | break; | |||
2439 | default: | |||
2440 | panic("unexpected msk_mib type"); | |||
2441 | /* NOTREACHED */ | |||
2442 | } | |||
2443 | } | |||
2444 | ||||
2445 | return (0); | |||
2446 | } | |||
2447 | #endif /* NKSTAT */ | |||
2448 | ||||
2449 | #ifdef MSK_DEBUG | |||
2450 | void | |||
2451 | msk_dump_txdesc(struct msk_tx_desc *le, int idx) | |||
2452 | { | |||
2453 | #define DESC_PRINT(X) \ | |||
2454 | if (X) \ | |||
2455 | printf("txdesc[%d]." #X "=%#x\n", \ | |||
2456 | idx, X); | |||
2457 | ||||
2458 | DESC_PRINT(letoh32(le->sk_addr)((__uint32_t)(le->sk_addr))); | |||
2459 | DESC_PRINT(letoh16(le->sk_len)((__uint16_t)(le->sk_len))); | |||
2460 | DESC_PRINT(le->sk_ctl); | |||
2461 | DESC_PRINT(le->sk_opcode); | |||
2462 | #undef DESC_PRINT | |||
2463 | } | |||
2464 | ||||
2465 | void | |||
2466 | msk_dump_bytes(const char *data, int len) | |||
2467 | { | |||
2468 | int c, i, j; | |||
2469 | ||||
2470 | for (i = 0; i < len; i += 16) { | |||
2471 | printf("%08x ", i); | |||
2472 | c = len - i; | |||
2473 | if (c > 16) c = 16; | |||
2474 | ||||
2475 | for (j = 0; j < c; j++) { | |||
2476 | printf("%02x ", data[i + j] & 0xff); | |||
2477 | if ((j & 0xf) == 7 && j > 0) | |||
2478 | printf(" "); | |||
2479 | } | |||
2480 | ||||
2481 | for (; j < 16; j++) | |||
2482 | printf(" "); | |||
2483 | printf(" "); | |||
2484 | ||||
2485 | for (j = 0; j < c; j++) { | |||
2486 | int ch = data[i + j] & 0xff; | |||
2487 | printf("%c", ' ' <= ch && ch <= '~' ? ch : ' '); | |||
2488 | } | |||
2489 | ||||
2490 | printf("\n"); | |||
2491 | ||||
2492 | if (c < 16) | |||
2493 | break; | |||
2494 | } | |||
2495 | } | |||
2496 | ||||
2497 | void | |||
2498 | msk_dump_mbuf(struct mbuf *m) | |||
2499 | { | |||
2500 | int count = m->m_pkthdrM_dat.MH.MH_pkthdr.len; | |||
2501 | ||||
2502 | printf("m=%#lx, m->m_pkthdr.len=%#d\n", m, m->m_pkthdrM_dat.MH.MH_pkthdr.len); | |||
2503 | ||||
2504 | while (count > 0 && m) { | |||
2505 | printf("m=%#lx, m->m_data=%#lx, m->m_len=%d\n", | |||
2506 | m, m->m_datam_hdr.mh_data, m->m_lenm_hdr.mh_len); | |||
2507 | msk_dump_bytes(mtod(m, char *)((char *)((m)->m_hdr.mh_data)), m->m_lenm_hdr.mh_len); | |||
2508 | ||||
2509 | count -= m->m_lenm_hdr.mh_len; | |||
2510 | m = m->m_nextm_hdr.mh_next; | |||
2511 | } | |||
2512 | } | |||
2513 | #endif |