if_xge.c revision 1.2.18.2 1 1.2.18.2 yamt /* $NetBSD: if_xge.c,v 1.2.18.2 2006/06/21 15:05:05 yamt Exp $ */
2 1.2.18.2 yamt
3 1.2.18.2 yamt /*
4 1.2.18.2 yamt * Copyright (c) 2004, SUNET, Swedish University Computer Network.
5 1.2.18.2 yamt * All rights reserved.
6 1.2.18.2 yamt *
7 1.2.18.2 yamt * Written by Anders Magnusson for SUNET, Swedish University Computer Network.
8 1.2.18.2 yamt *
9 1.2.18.2 yamt * Redistribution and use in source and binary forms, with or without
10 1.2.18.2 yamt * modification, are permitted provided that the following conditions
11 1.2.18.2 yamt * are met:
12 1.2.18.2 yamt * 1. Redistributions of source code must retain the above copyright
13 1.2.18.2 yamt * notice, this list of conditions and the following disclaimer.
14 1.2.18.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
15 1.2.18.2 yamt * notice, this list of conditions and the following disclaimer in the
16 1.2.18.2 yamt * documentation and/or other materials provided with the distribution.
17 1.2.18.2 yamt * 3. All advertising materials mentioning features or use of this software
18 1.2.18.2 yamt * must display the following acknowledgement:
19 1.2.18.2 yamt * This product includes software developed for the NetBSD Project by
20 1.2.18.2 yamt * SUNET, Swedish University Computer Network.
21 1.2.18.2 yamt * 4. The name of SUNET may not be used to endorse or promote products
22 1.2.18.2 yamt * derived from this software without specific prior written permission.
23 1.2.18.2 yamt *
24 1.2.18.2 yamt * THIS SOFTWARE IS PROVIDED BY SUNET ``AS IS'' AND
25 1.2.18.2 yamt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 1.2.18.2 yamt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 1.2.18.2 yamt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUNET
28 1.2.18.2 yamt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 1.2.18.2 yamt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 1.2.18.2 yamt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 1.2.18.2 yamt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 1.2.18.2 yamt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 1.2.18.2 yamt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 1.2.18.2 yamt * POSSIBILITY OF SUCH DAMAGE.
35 1.2.18.2 yamt */
36 1.2.18.2 yamt
37 1.2.18.2 yamt /*
38 1.2.18.2 yamt * Device driver for the S2io Xframe Ten Gigabit Ethernet controller.
39 1.2.18.2 yamt *
40 1.2.18.2 yamt * TODO (in no specific order):
41 1.2.18.2 yamt * HW VLAN support.
42 1.2.18.2 yamt * IPv6 HW cksum.
43 1.2.18.2 yamt */
44 1.2.18.2 yamt
45 1.2.18.2 yamt #include <sys/cdefs.h>
46 1.2.18.2 yamt __KERNEL_RCSID(0, "$NetBSD: if_xge.c,v 1.2.18.2 2006/06/21 15:05:05 yamt Exp $");
47 1.2.18.2 yamt
48 1.2.18.2 yamt #include "bpfilter.h"
49 1.2.18.2 yamt #include "rnd.h"
50 1.2.18.2 yamt
51 1.2.18.2 yamt #include <sys/param.h>
52 1.2.18.2 yamt #include <sys/systm.h>
53 1.2.18.2 yamt #include <sys/mbuf.h>
54 1.2.18.2 yamt #include <sys/malloc.h>
55 1.2.18.2 yamt #include <sys/kernel.h>
56 1.2.18.2 yamt #include <sys/socket.h>
57 1.2.18.2 yamt #include <sys/device.h>
58 1.2.18.2 yamt
59 1.2.18.2 yamt #if NRND > 0
60 1.2.18.2 yamt #include <sys/rnd.h>
61 1.2.18.2 yamt #endif
62 1.2.18.2 yamt
63 1.2.18.2 yamt #include <net/if.h>
64 1.2.18.2 yamt #include <net/if_dl.h>
65 1.2.18.2 yamt #include <net/if_media.h>
66 1.2.18.2 yamt #include <net/if_ether.h>
67 1.2.18.2 yamt
68 1.2.18.2 yamt #if NBPFILTER > 0
69 1.2.18.2 yamt #include <net/bpf.h>
70 1.2.18.2 yamt #endif
71 1.2.18.2 yamt
72 1.2.18.2 yamt #include <machine/bus.h>
73 1.2.18.2 yamt #include <machine/intr.h>
74 1.2.18.2 yamt #include <machine/endian.h>
75 1.2.18.2 yamt
76 1.2.18.2 yamt #include <dev/mii/mii.h>
77 1.2.18.2 yamt #include <dev/mii/miivar.h>
78 1.2.18.2 yamt
79 1.2.18.2 yamt #include <dev/pci/pcivar.h>
80 1.2.18.2 yamt #include <dev/pci/pcireg.h>
81 1.2.18.2 yamt #include <dev/pci/pcidevs.h>
82 1.2.18.2 yamt
83 1.2.18.2 yamt #include <sys/lock.h>
84 1.2.18.2 yamt #include <sys/proc.h>
85 1.2.18.2 yamt
86 1.2.18.2 yamt #include <dev/pci/if_xgereg.h>
87 1.2.18.2 yamt
88 1.2.18.2 yamt /*
89 1.2.18.2 yamt * Some tunable constants, tune with care!
90 1.2.18.2 yamt */
91 1.2.18.2 yamt #define RX_MODE RX_MODE_1 /* Receive mode (buffer usage, see below) */
92 1.2.18.2 yamt #define NRXDESCS 1016 /* # of receive descriptors (requested) */
93 1.2.18.2 yamt #define NTXDESCS 8192 /* Number of transmit descriptors */
94 1.2.18.2 yamt #define NTXFRAGS 100 /* Max fragments per packet */
95 1.2.18.2 yamt #define XGE_EVENT_COUNTERS /* Instrumentation */
96 1.2.18.2 yamt
97 1.2.18.2 yamt /*
98 1.2.18.2 yamt * Receive buffer modes; 1, 3 or 5 buffers.
99 1.2.18.2 yamt */
100 1.2.18.2 yamt #define RX_MODE_1 1
101 1.2.18.2 yamt #define RX_MODE_3 3
102 1.2.18.2 yamt #define RX_MODE_5 5
103 1.2.18.2 yamt
104 1.2.18.2 yamt /*
105 1.2.18.2 yamt * Use clever macros to avoid a bunch of #ifdef's.
106 1.2.18.2 yamt */
107 1.2.18.2 yamt #define XCONCAT3(x,y,z) x ## y ## z
108 1.2.18.2 yamt #define CONCAT3(x,y,z) XCONCAT3(x,y,z)
109 1.2.18.2 yamt #define NDESC_BUFMODE CONCAT3(NDESC_,RX_MODE,BUFMODE)
110 1.2.18.2 yamt #define rxd_4k CONCAT3(rxd,RX_MODE,_4k)
111 1.2.18.2 yamt #define rxdesc ___CONCAT(rxd,RX_MODE)
112 1.2.18.2 yamt
113 1.2.18.2 yamt #define NEXTTX(x) (((x)+1) % NTXDESCS)
114 1.2.18.2 yamt #define NRXFRAGS RX_MODE /* hardware imposed frags */
115 1.2.18.2 yamt #define NRXPAGES ((NRXDESCS/NDESC_BUFMODE)+1)
116 1.2.18.2 yamt #define NRXREAL (NRXPAGES*NDESC_BUFMODE)
117 1.2.18.2 yamt #define RXMAPSZ (NRXPAGES*PAGE_SIZE)
118 1.2.18.2 yamt
119 1.2.18.2 yamt #ifdef XGE_EVENT_COUNTERS
120 1.2.18.2 yamt #define XGE_EVCNT_INCR(ev) (ev)->ev_count++
121 1.2.18.2 yamt #else
122 1.2.18.2 yamt #define XGE_EVCNT_INCR(ev) /* nothing */
123 1.2.18.2 yamt #endif
124 1.2.18.2 yamt
125 1.2.18.2 yamt /*
126 1.2.18.2 yamt * Magics to fix a bug when the mac address can't be read correctly.
127 1.2.18.2 yamt * Comes from the Linux driver.
128 1.2.18.2 yamt */
129 1.2.18.2 yamt static uint64_t fix_mac[] = {
130 1.2.18.2 yamt 0x0060000000000000ULL, 0x0060600000000000ULL,
131 1.2.18.2 yamt 0x0040600000000000ULL, 0x0000600000000000ULL,
132 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
133 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
134 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
135 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
136 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
137 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
138 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
139 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
140 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
141 1.2.18.2 yamt 0x0020600000000000ULL, 0x0060600000000000ULL,
142 1.2.18.2 yamt 0x0020600000000000ULL, 0x0000600000000000ULL,
143 1.2.18.2 yamt 0x0040600000000000ULL, 0x0060600000000000ULL,
144 1.2.18.2 yamt };
145 1.2.18.2 yamt
146 1.2.18.2 yamt
147 1.2.18.2 yamt struct xge_softc {
148 1.2.18.2 yamt struct device sc_dev;
149 1.2.18.2 yamt struct ethercom sc_ethercom;
150 1.2.18.2 yamt #define sc_if sc_ethercom.ec_if
151 1.2.18.2 yamt bus_dma_tag_t sc_dmat;
152 1.2.18.2 yamt bus_space_tag_t sc_st;
153 1.2.18.2 yamt bus_space_handle_t sc_sh;
154 1.2.18.2 yamt bus_space_tag_t sc_txt;
155 1.2.18.2 yamt bus_space_handle_t sc_txh;
156 1.2.18.2 yamt void *sc_ih;
157 1.2.18.2 yamt
158 1.2.18.2 yamt struct ifmedia xena_media;
159 1.2.18.2 yamt pcireg_t sc_pciregs[16];
160 1.2.18.2 yamt
161 1.2.18.2 yamt /* Transmit structures */
162 1.2.18.2 yamt struct txd *sc_txd[NTXDESCS]; /* transmit frags array */
163 1.2.18.2 yamt bus_addr_t sc_txdp[NTXDESCS]; /* bus address of transmit frags */
164 1.2.18.2 yamt bus_dmamap_t sc_txm[NTXDESCS]; /* transmit frags map */
165 1.2.18.2 yamt struct mbuf *sc_txb[NTXDESCS]; /* transmit mbuf pointer */
166 1.2.18.2 yamt int sc_nexttx, sc_lasttx;
167 1.2.18.2 yamt bus_dmamap_t sc_txmap; /* transmit descriptor map */
168 1.2.18.2 yamt
169 1.2.18.2 yamt /* Receive data */
170 1.2.18.2 yamt bus_dmamap_t sc_rxmap; /* receive descriptor map */
171 1.2.18.2 yamt struct rxd_4k *sc_rxd_4k[NRXPAGES]; /* receive desc pages */
172 1.2.18.2 yamt bus_dmamap_t sc_rxm[NRXREAL]; /* receive buffer map */
173 1.2.18.2 yamt struct mbuf *sc_rxb[NRXREAL]; /* mbufs on receive descriptors */
174 1.2.18.2 yamt int sc_nextrx; /* next descriptor to check */
175 1.2.18.2 yamt
176 1.2.18.2 yamt #ifdef XGE_EVENT_COUNTERS
177 1.2.18.2 yamt struct evcnt sc_intr; /* # of interrupts */
178 1.2.18.2 yamt struct evcnt sc_txintr; /* # of transmit interrupts */
179 1.2.18.2 yamt struct evcnt sc_rxintr; /* # of receive interrupts */
180 1.2.18.2 yamt struct evcnt sc_txqe; /* # of xmit intrs when board queue empty */
181 1.2.18.2 yamt #endif
182 1.2.18.2 yamt };
183 1.2.18.2 yamt
184 1.2.18.2 yamt static int xge_match(struct device *parent, struct cfdata *cf, void *aux);
185 1.2.18.2 yamt static void xge_attach(struct device *parent, struct device *self, void *aux);
186 1.2.18.2 yamt static int xge_alloc_txmem(struct xge_softc *);
187 1.2.18.2 yamt static int xge_alloc_rxmem(struct xge_softc *);
188 1.2.18.2 yamt static void xge_start(struct ifnet *);
189 1.2.18.2 yamt static void xge_stop(struct ifnet *, int);
190 1.2.18.2 yamt static int xge_add_rxbuf(struct xge_softc *, int);
191 1.2.18.2 yamt static void xge_mcast_filter(struct xge_softc *sc);
192 1.2.18.2 yamt static int xge_setup_xgxs(struct xge_softc *sc);
193 1.2.18.2 yamt static int xge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
194 1.2.18.2 yamt static int xge_init(struct ifnet *ifp);
195 1.2.18.2 yamt static void xge_ifmedia_status(struct ifnet *, struct ifmediareq *);
196 1.2.18.2 yamt static int xge_xgmii_mediachange(struct ifnet *);
197 1.2.18.2 yamt static int xge_intr(void *);
198 1.2.18.2 yamt
199 1.2.18.2 yamt /*
200 1.2.18.2 yamt * Helpers to address registers.
201 1.2.18.2 yamt */
202 1.2.18.2 yamt #define PIF_WCSR(csr, val) pif_wcsr(sc, csr, val)
203 1.2.18.2 yamt #define PIF_RCSR(csr) pif_rcsr(sc, csr)
204 1.2.18.2 yamt #define TXP_WCSR(csr, val) txp_wcsr(sc, csr, val)
205 1.2.18.2 yamt #define PIF_WKEY(csr, val) pif_wkey(sc, csr, val)
206 1.2.18.2 yamt
207 1.2.18.2 yamt static inline void
208 1.2.18.2 yamt pif_wcsr(struct xge_softc *sc, bus_size_t csr, uint64_t val)
209 1.2.18.2 yamt {
210 1.2.18.2 yamt uint32_t lval, hval;
211 1.2.18.2 yamt
212 1.2.18.2 yamt lval = val&0xffffffff;
213 1.2.18.2 yamt hval = val>>32;
214 1.2.18.2 yamt bus_space_write_4(sc->sc_st, sc->sc_sh, csr, lval);
215 1.2.18.2 yamt bus_space_write_4(sc->sc_st, sc->sc_sh, csr+4, hval);
216 1.2.18.2 yamt }
217 1.2.18.2 yamt
218 1.2.18.2 yamt static inline uint64_t
219 1.2.18.2 yamt pif_rcsr(struct xge_softc *sc, bus_size_t csr)
220 1.2.18.2 yamt {
221 1.2.18.2 yamt uint64_t val, val2;
222 1.2.18.2 yamt val = bus_space_read_4(sc->sc_st, sc->sc_sh, csr);
223 1.2.18.2 yamt val2 = bus_space_read_4(sc->sc_st, sc->sc_sh, csr+4);
224 1.2.18.2 yamt val |= (val2 << 32);
225 1.2.18.2 yamt return val;
226 1.2.18.2 yamt }
227 1.2.18.2 yamt
228 1.2.18.2 yamt static inline void
229 1.2.18.2 yamt txp_wcsr(struct xge_softc *sc, bus_size_t csr, uint64_t val)
230 1.2.18.2 yamt {
231 1.2.18.2 yamt uint32_t lval, hval;
232 1.2.18.2 yamt
233 1.2.18.2 yamt lval = val&0xffffffff;
234 1.2.18.2 yamt hval = val>>32;
235 1.2.18.2 yamt bus_space_write_4(sc->sc_txt, sc->sc_txh, csr, lval);
236 1.2.18.2 yamt bus_space_write_4(sc->sc_txt, sc->sc_txh, csr+4, hval);
237 1.2.18.2 yamt }
238 1.2.18.2 yamt
239 1.2.18.2 yamt
240 1.2.18.2 yamt static inline void
241 1.2.18.2 yamt pif_wkey(struct xge_softc *sc, bus_size_t csr, uint64_t val)
242 1.2.18.2 yamt {
243 1.2.18.2 yamt uint32_t lval, hval;
244 1.2.18.2 yamt
245 1.2.18.2 yamt lval = val&0xffffffff;
246 1.2.18.2 yamt hval = val>>32;
247 1.2.18.2 yamt PIF_WCSR(RMAC_CFG_KEY, RMAC_KEY_VALUE);
248 1.2.18.2 yamt bus_space_write_4(sc->sc_st, sc->sc_sh, csr, lval);
249 1.2.18.2 yamt PIF_WCSR(RMAC_CFG_KEY, RMAC_KEY_VALUE);
250 1.2.18.2 yamt bus_space_write_4(sc->sc_st, sc->sc_sh, csr+4, hval);
251 1.2.18.2 yamt }
252 1.2.18.2 yamt
253 1.2.18.2 yamt
254 1.2.18.2 yamt CFATTACH_DECL(xge, sizeof(struct xge_softc),
255 1.2.18.2 yamt xge_match, xge_attach, NULL, NULL);
256 1.2.18.2 yamt
257 1.2.18.2 yamt #define XNAME sc->sc_dev.dv_xname
258 1.2.18.2 yamt
259 1.2.18.2 yamt #define XGE_RXSYNC(desc, what) \
260 1.2.18.2 yamt bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap, \
261 1.2.18.2 yamt (desc/NDESC_BUFMODE) * XGE_PAGE + sizeof(struct rxdesc) * \
262 1.2.18.2 yamt (desc%NDESC_BUFMODE), sizeof(struct rxdesc), what)
263 1.2.18.2 yamt #define XGE_RXD(desc) &sc->sc_rxd_4k[desc/NDESC_BUFMODE]-> \
264 1.2.18.2 yamt r4_rxd[desc%NDESC_BUFMODE]
265 1.2.18.2 yamt
266 1.2.18.2 yamt /*
267 1.2.18.2 yamt * Non-tunable constants.
268 1.2.18.2 yamt */
269 1.2.18.2 yamt #define XGE_MAX_MTU 9600
270 1.2.18.2 yamt #define XGE_IP_MAXPACKET 65535 /* same as IP_MAXPACKET */
271 1.2.18.2 yamt
272 1.2.18.2 yamt static int
273 1.2.18.2 yamt xge_match(struct device *parent, struct cfdata *cf, void *aux)
274 1.2.18.2 yamt {
275 1.2.18.2 yamt struct pci_attach_args *pa = aux;
276 1.2.18.2 yamt
277 1.2.18.2 yamt if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_S2IO &&
278 1.2.18.2 yamt PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_S2IO_XFRAME)
279 1.2.18.2 yamt return (1);
280 1.2.18.2 yamt
281 1.2.18.2 yamt return (0);
282 1.2.18.2 yamt }
283 1.2.18.2 yamt
284 1.2.18.2 yamt void
285 1.2.18.2 yamt xge_attach(struct device *parent, struct device *self, void *aux)
286 1.2.18.2 yamt {
287 1.2.18.2 yamt struct pci_attach_args *pa = aux;
288 1.2.18.2 yamt struct xge_softc *sc;
289 1.2.18.2 yamt struct ifnet *ifp;
290 1.2.18.2 yamt pcireg_t memtype;
291 1.2.18.2 yamt pci_intr_handle_t ih;
292 1.2.18.2 yamt const char *intrstr = NULL;
293 1.2.18.2 yamt pci_chipset_tag_t pc = pa->pa_pc;
294 1.2.18.2 yamt uint8_t enaddr[ETHER_ADDR_LEN];
295 1.2.18.2 yamt uint64_t val;
296 1.2.18.2 yamt int i;
297 1.2.18.2 yamt
298 1.2.18.2 yamt sc = (struct xge_softc *)self;
299 1.2.18.2 yamt
300 1.2.18.2 yamt sc->sc_dmat = pa->pa_dmat;
301 1.2.18.2 yamt
302 1.2.18.2 yamt /* Get BAR0 address */
303 1.2.18.2 yamt memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, XGE_PIF_BAR);
304 1.2.18.2 yamt if (pci_mapreg_map(pa, XGE_PIF_BAR, memtype, 0,
305 1.2.18.2 yamt &sc->sc_st, &sc->sc_sh, 0, 0)) {
306 1.2.18.2 yamt aprint_error("%s: unable to map PIF BAR registers\n", XNAME);
307 1.2.18.2 yamt return;
308 1.2.18.2 yamt }
309 1.2.18.2 yamt
310 1.2.18.2 yamt memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, XGE_TXP_BAR);
311 1.2.18.2 yamt if (pci_mapreg_map(pa, XGE_TXP_BAR, memtype, 0,
312 1.2.18.2 yamt &sc->sc_txt, &sc->sc_txh, 0, 0)) {
313 1.2.18.2 yamt aprint_error("%s: unable to map TXP BAR registers\n", XNAME);
314 1.2.18.2 yamt return;
315 1.2.18.2 yamt }
316 1.2.18.2 yamt
317 1.2.18.2 yamt /* Save PCI config space */
318 1.2.18.2 yamt for (i = 0; i < 64; i += 4)
319 1.2.18.2 yamt sc->sc_pciregs[i/4] = pci_conf_read(pa->pa_pc, pa->pa_tag, i);
320 1.2.18.2 yamt
321 1.2.18.2 yamt #if BYTE_ORDER == LITTLE_ENDIAN
322 1.2.18.2 yamt val = (uint64_t)0xFFFFFFFFFFFFFFFFULL;
323 1.2.18.2 yamt val &= ~(TxF_R_SE|RxF_W_SE);
324 1.2.18.2 yamt PIF_WCSR(SWAPPER_CTRL, val);
325 1.2.18.2 yamt PIF_WCSR(SWAPPER_CTRL, val);
326 1.2.18.2 yamt #elif BYTE_ORDER == BIG_ENDIAN
327 1.2.18.2 yamt /* do nothing */
328 1.2.18.2 yamt #else
329 1.2.18.2 yamt #error bad endianness!
330 1.2.18.2 yamt #endif
331 1.2.18.2 yamt
332 1.2.18.2 yamt if ((val = PIF_RCSR(PIF_RD_SWAPPER_Fb)) != SWAPPER_MAGIC)
333 1.2.18.2 yamt return printf("%s: failed configuring endian, %llx != %llx!\n",
334 1.2.18.2 yamt XNAME, (unsigned long long)val, SWAPPER_MAGIC);
335 1.2.18.2 yamt
336 1.2.18.2 yamt /*
337 1.2.18.2 yamt * The MAC addr may be all FF's, which is not good.
338 1.2.18.2 yamt * Resolve it by writing some magics to GPIO_CONTROL and
339 1.2.18.2 yamt * force a chip reset to read in the serial eeprom again.
340 1.2.18.2 yamt */
341 1.2.18.2 yamt for (i = 0; i < sizeof(fix_mac)/sizeof(fix_mac[0]); i++) {
342 1.2.18.2 yamt PIF_WCSR(GPIO_CONTROL, fix_mac[i]);
343 1.2.18.2 yamt PIF_RCSR(GPIO_CONTROL);
344 1.2.18.2 yamt }
345 1.2.18.2 yamt
346 1.2.18.2 yamt /*
347 1.2.18.2 yamt * Reset the chip and restore the PCI registers.
348 1.2.18.2 yamt */
349 1.2.18.2 yamt PIF_WCSR(SW_RESET, 0xa5a5a50000000000ULL);
350 1.2.18.2 yamt DELAY(500000);
351 1.2.18.2 yamt for (i = 0; i < 64; i += 4)
352 1.2.18.2 yamt pci_conf_write(pa->pa_pc, pa->pa_tag, i, sc->sc_pciregs[i/4]);
353 1.2.18.2 yamt
354 1.2.18.2 yamt /*
355 1.2.18.2 yamt * Restore the byte order registers.
356 1.2.18.2 yamt */
357 1.2.18.2 yamt #if BYTE_ORDER == LITTLE_ENDIAN
358 1.2.18.2 yamt val = (uint64_t)0xFFFFFFFFFFFFFFFFULL;
359 1.2.18.2 yamt val &= ~(TxF_R_SE|RxF_W_SE);
360 1.2.18.2 yamt PIF_WCSR(SWAPPER_CTRL, val);
361 1.2.18.2 yamt PIF_WCSR(SWAPPER_CTRL, val);
362 1.2.18.2 yamt #elif BYTE_ORDER == BIG_ENDIAN
363 1.2.18.2 yamt /* do nothing */
364 1.2.18.2 yamt #else
365 1.2.18.2 yamt #error bad endianness!
366 1.2.18.2 yamt #endif
367 1.2.18.2 yamt
368 1.2.18.2 yamt if ((val = PIF_RCSR(PIF_RD_SWAPPER_Fb)) != SWAPPER_MAGIC)
369 1.2.18.2 yamt return printf("%s: failed configuring endian2, %llx != %llx!\n",
370 1.2.18.2 yamt XNAME, (unsigned long long)val, SWAPPER_MAGIC);
371 1.2.18.2 yamt
372 1.2.18.2 yamt /*
373 1.2.18.2 yamt * XGXS initialization.
374 1.2.18.2 yamt */
375 1.2.18.2 yamt /* 29, reset */
376 1.2.18.2 yamt PIF_WCSR(SW_RESET, 0);
377 1.2.18.2 yamt DELAY(500000);
378 1.2.18.2 yamt
379 1.2.18.2 yamt /* 30, configure XGXS transceiver */
380 1.2.18.2 yamt xge_setup_xgxs(sc);
381 1.2.18.2 yamt
382 1.2.18.2 yamt /* 33, program MAC address (not needed here) */
383 1.2.18.2 yamt /* Get ethernet address */
384 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_CMD_MEM,
385 1.2.18.2 yamt RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(0));
386 1.2.18.2 yamt while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
387 1.2.18.2 yamt ;
388 1.2.18.2 yamt val = PIF_RCSR(RMAC_ADDR_DATA0_MEM);
389 1.2.18.2 yamt for (i = 0; i < ETHER_ADDR_LEN; i++)
390 1.2.18.2 yamt enaddr[i] = (uint8_t)(val >> (56 - (8*i)));
391 1.2.18.2 yamt
392 1.2.18.2 yamt /*
393 1.2.18.2 yamt * Get memory for transmit descriptor lists.
394 1.2.18.2 yamt */
395 1.2.18.2 yamt if (xge_alloc_txmem(sc))
396 1.2.18.2 yamt return printf("%s: failed allocating txmem.\n", XNAME);
397 1.2.18.2 yamt
398 1.2.18.2 yamt /* 9 and 10 - set FIFO number/prio */
399 1.2.18.2 yamt PIF_WCSR(TX_FIFO_P0, TX_FIFO_LEN0(NTXDESCS));
400 1.2.18.2 yamt PIF_WCSR(TX_FIFO_P1, 0ULL);
401 1.2.18.2 yamt PIF_WCSR(TX_FIFO_P2, 0ULL);
402 1.2.18.2 yamt PIF_WCSR(TX_FIFO_P3, 0ULL);
403 1.2.18.2 yamt
404 1.2.18.2 yamt /* 11, XXX set round-robin prio? */
405 1.2.18.2 yamt
406 1.2.18.2 yamt /* 12, enable transmit FIFO */
407 1.2.18.2 yamt val = PIF_RCSR(TX_FIFO_P0);
408 1.2.18.2 yamt val |= TX_FIFO_ENABLE;
409 1.2.18.2 yamt PIF_WCSR(TX_FIFO_P0, val);
410 1.2.18.2 yamt
411 1.2.18.2 yamt /* 13, disable some error checks */
412 1.2.18.2 yamt PIF_WCSR(TX_PA_CFG,
413 1.2.18.2 yamt TX_PA_CFG_IFR|TX_PA_CFG_ISO|TX_PA_CFG_ILC|TX_PA_CFG_ILE);
414 1.2.18.2 yamt
415 1.2.18.2 yamt /*
416 1.2.18.2 yamt * Create transmit DMA maps.
417 1.2.18.2 yamt * Make them large for TSO.
418 1.2.18.2 yamt */
419 1.2.18.2 yamt for (i = 0; i < NTXDESCS; i++) {
420 1.2.18.2 yamt if (bus_dmamap_create(sc->sc_dmat, XGE_IP_MAXPACKET,
421 1.2.18.2 yamt NTXFRAGS, MCLBYTES, 0, 0, &sc->sc_txm[i]))
422 1.2.18.2 yamt return printf("%s: cannot create TX DMA maps\n", XNAME);
423 1.2.18.2 yamt }
424 1.2.18.2 yamt
425 1.2.18.2 yamt sc->sc_lasttx = NTXDESCS-1;
426 1.2.18.2 yamt
427 1.2.18.2 yamt /*
428 1.2.18.2 yamt * RxDMA initialization.
429 1.2.18.2 yamt * Only use one out of 8 possible receive queues.
430 1.2.18.2 yamt */
431 1.2.18.2 yamt if (xge_alloc_rxmem(sc)) /* allocate rx descriptor memory */
432 1.2.18.2 yamt return printf("%s: failed allocating rxmem\n", XNAME);
433 1.2.18.2 yamt
434 1.2.18.2 yamt /* Create receive buffer DMA maps */
435 1.2.18.2 yamt for (i = 0; i < NRXREAL; i++) {
436 1.2.18.2 yamt if (bus_dmamap_create(sc->sc_dmat, XGE_MAX_MTU,
437 1.2.18.2 yamt NRXFRAGS, MCLBYTES, 0, 0, &sc->sc_rxm[i]))
438 1.2.18.2 yamt return printf("%s: cannot create RX DMA maps\n", XNAME);
439 1.2.18.2 yamt }
440 1.2.18.2 yamt
441 1.2.18.2 yamt /* allocate mbufs to receive descriptors */
442 1.2.18.2 yamt for (i = 0; i < NRXREAL; i++)
443 1.2.18.2 yamt if (xge_add_rxbuf(sc, i))
444 1.2.18.2 yamt panic("out of mbufs too early");
445 1.2.18.2 yamt
446 1.2.18.2 yamt /* 14, setup receive ring priority */
447 1.2.18.2 yamt PIF_WCSR(RX_QUEUE_PRIORITY, 0ULL); /* only use one ring */
448 1.2.18.2 yamt
449 1.2.18.2 yamt /* 15, setup receive ring round-robin calendar */
450 1.2.18.2 yamt PIF_WCSR(RX_W_ROUND_ROBIN_0, 0ULL); /* only use one ring */
451 1.2.18.2 yamt PIF_WCSR(RX_W_ROUND_ROBIN_1, 0ULL);
452 1.2.18.2 yamt PIF_WCSR(RX_W_ROUND_ROBIN_2, 0ULL);
453 1.2.18.2 yamt PIF_WCSR(RX_W_ROUND_ROBIN_3, 0ULL);
454 1.2.18.2 yamt PIF_WCSR(RX_W_ROUND_ROBIN_4, 0ULL);
455 1.2.18.2 yamt
456 1.2.18.2 yamt /* 16, write receive ring start address */
457 1.2.18.2 yamt PIF_WCSR(PRC_RXD0_0, (uint64_t)sc->sc_rxmap->dm_segs[0].ds_addr);
458 1.2.18.2 yamt /* PRC_RXD0_[1-7] are not used */
459 1.2.18.2 yamt
460 1.2.18.2 yamt /* 17, Setup alarm registers */
461 1.2.18.2 yamt PIF_WCSR(PRC_ALARM_ACTION, 0ULL); /* Default everything to retry */
462 1.2.18.2 yamt
463 1.2.18.2 yamt /* 18, init receive ring controller */
464 1.2.18.2 yamt #if RX_MODE == RX_MODE_1
465 1.2.18.2 yamt val = RING_MODE_1;
466 1.2.18.2 yamt #elif RX_MODE == RX_MODE_3
467 1.2.18.2 yamt val = RING_MODE_3;
468 1.2.18.2 yamt #else /* RX_MODE == RX_MODE_5 */
469 1.2.18.2 yamt val = RING_MODE_5;
470 1.2.18.2 yamt #endif
471 1.2.18.2 yamt PIF_WCSR(PRC_CTRL_0, RC_IN_SVC|val);
472 1.2.18.2 yamt /* leave 1-7 disabled */
473 1.2.18.2 yamt /* XXXX snoop configuration? */
474 1.2.18.2 yamt
475 1.2.18.2 yamt /* 19, set chip memory assigned to the queue */
476 1.2.18.2 yamt PIF_WCSR(RX_QUEUE_CFG, MC_QUEUE(0, 64)); /* all 64M to queue 0 */
477 1.2.18.2 yamt
478 1.2.18.2 yamt /* 20, setup RLDRAM parameters */
479 1.2.18.2 yamt /* do not touch it for now */
480 1.2.18.2 yamt
481 1.2.18.2 yamt /* 21, setup pause frame thresholds */
482 1.2.18.2 yamt /* so not touch the defaults */
483 1.2.18.2 yamt /* XXX - must 0xff be written as stated in the manual? */
484 1.2.18.2 yamt
485 1.2.18.2 yamt /* 22, configure RED */
486 1.2.18.2 yamt /* we do not want to drop packets, so ignore */
487 1.2.18.2 yamt
488 1.2.18.2 yamt /* 23, initiate RLDRAM */
489 1.2.18.2 yamt val = PIF_RCSR(MC_RLDRAM_MRS);
490 1.2.18.2 yamt val |= MC_QUEUE_SIZE_ENABLE|MC_RLDRAM_MRS_ENABLE;
491 1.2.18.2 yamt PIF_WCSR(MC_RLDRAM_MRS, val);
492 1.2.18.2 yamt DELAY(1000);
493 1.2.18.2 yamt
494 1.2.18.2 yamt /*
495 1.2.18.2 yamt * Setup interrupt policies.
496 1.2.18.2 yamt */
497 1.2.18.2 yamt /* 40, Transmit interrupts */
498 1.2.18.2 yamt PIF_WCSR(TTI_DATA1_MEM, TX_TIMER_VAL(0x1ff) | TX_TIMER_AC |
499 1.2.18.2 yamt TX_URNG_A(5) | TX_URNG_B(20) | TX_URNG_C(48));
500 1.2.18.2 yamt PIF_WCSR(TTI_DATA2_MEM,
501 1.2.18.2 yamt TX_UFC_A(25) | TX_UFC_B(64) | TX_UFC_C(128) | TX_UFC_D(512));
502 1.2.18.2 yamt PIF_WCSR(TTI_COMMAND_MEM, TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE);
503 1.2.18.2 yamt while (PIF_RCSR(TTI_COMMAND_MEM) & TTI_CMD_MEM_STROBE)
504 1.2.18.2 yamt ;
505 1.2.18.2 yamt
506 1.2.18.2 yamt /* 41, Receive interrupts */
507 1.2.18.2 yamt PIF_WCSR(RTI_DATA1_MEM, RX_TIMER_VAL(0x800) | RX_TIMER_AC |
508 1.2.18.2 yamt RX_URNG_A(5) | RX_URNG_B(20) | RX_URNG_C(50));
509 1.2.18.2 yamt PIF_WCSR(RTI_DATA2_MEM,
510 1.2.18.2 yamt RX_UFC_A(64) | RX_UFC_B(128) | RX_UFC_C(256) | RX_UFC_D(512));
511 1.2.18.2 yamt PIF_WCSR(RTI_COMMAND_MEM, RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE);
512 1.2.18.2 yamt while (PIF_RCSR(RTI_COMMAND_MEM) & RTI_CMD_MEM_STROBE)
513 1.2.18.2 yamt ;
514 1.2.18.2 yamt
515 1.2.18.2 yamt /*
516 1.2.18.2 yamt * Setup media stuff.
517 1.2.18.2 yamt */
518 1.2.18.2 yamt ifmedia_init(&sc->xena_media, IFM_IMASK, xge_xgmii_mediachange,
519 1.2.18.2 yamt xge_ifmedia_status);
520 1.2.18.2 yamt ifmedia_add(&sc->xena_media, IFM_ETHER|IFM_10G_LR, 0, NULL);
521 1.2.18.2 yamt ifmedia_set(&sc->xena_media, IFM_ETHER|IFM_10G_LR);
522 1.2.18.2 yamt
523 1.2.18.2 yamt aprint_normal("%s: Ethernet address %s\n", XNAME,
524 1.2.18.2 yamt ether_sprintf(enaddr));
525 1.2.18.2 yamt
526 1.2.18.2 yamt ifp = &sc->sc_ethercom.ec_if;
527 1.2.18.2 yamt strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
528 1.2.18.2 yamt ifp->if_baudrate = 10000000000LL;
529 1.2.18.2 yamt ifp->if_init = xge_init;
530 1.2.18.2 yamt ifp->if_stop = xge_stop;
531 1.2.18.2 yamt ifp->if_softc = sc;
532 1.2.18.2 yamt ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
533 1.2.18.2 yamt ifp->if_ioctl = xge_ioctl;
534 1.2.18.2 yamt ifp->if_start = xge_start;
535 1.2.18.2 yamt IFQ_SET_MAXLEN(&ifp->if_snd, max(NTXDESCS - 1, IFQ_MAXLEN));
536 1.2.18.2 yamt IFQ_SET_READY(&ifp->if_snd);
537 1.2.18.2 yamt
538 1.2.18.2 yamt /*
539 1.2.18.2 yamt * Offloading capabilities.
540 1.2.18.2 yamt */
541 1.2.18.2 yamt sc->sc_ethercom.ec_capabilities |=
542 1.2.18.2 yamt ETHERCAP_JUMBO_MTU | ETHERCAP_VLAN_MTU;
543 1.2.18.2 yamt ifp->if_capabilities |=
544 1.2.18.2 yamt IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx |
545 1.2.18.2 yamt IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx |
546 1.2.18.2 yamt IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_UDPv4_Tx | IFCAP_TSOv4;
547 1.2.18.2 yamt
548 1.2.18.2 yamt /*
549 1.2.18.2 yamt * Attach the interface.
550 1.2.18.2 yamt */
551 1.2.18.2 yamt if_attach(ifp);
552 1.2.18.2 yamt ether_ifattach(ifp, enaddr);
553 1.2.18.2 yamt
554 1.2.18.2 yamt /*
555 1.2.18.2 yamt * Setup interrupt vector before initializing.
556 1.2.18.2 yamt */
557 1.2.18.2 yamt if (pci_intr_map(pa, &ih))
558 1.2.18.2 yamt return aprint_error("%s: unable to map interrupt\n",
559 1.2.18.2 yamt sc->sc_dev.dv_xname);
560 1.2.18.2 yamt intrstr = pci_intr_string(pc, ih);
561 1.2.18.2 yamt if ((sc->sc_ih =
562 1.2.18.2 yamt pci_intr_establish(pc, ih, IPL_NET, xge_intr, sc)) == NULL)
563 1.2.18.2 yamt return aprint_error("%s: unable to establish interrupt at %s\n",
564 1.2.18.2 yamt sc->sc_dev.dv_xname, intrstr ? intrstr : "<unknown>");
565 1.2.18.2 yamt aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
566 1.2.18.2 yamt
567 1.2.18.2 yamt #ifdef XGE_EVENT_COUNTERS
568 1.2.18.2 yamt evcnt_attach_dynamic(&sc->sc_intr, EVCNT_TYPE_MISC,
569 1.2.18.2 yamt NULL, XNAME, "intr");
570 1.2.18.2 yamt evcnt_attach_dynamic(&sc->sc_txintr, EVCNT_TYPE_MISC,
571 1.2.18.2 yamt NULL, XNAME, "txintr");
572 1.2.18.2 yamt evcnt_attach_dynamic(&sc->sc_rxintr, EVCNT_TYPE_MISC,
573 1.2.18.2 yamt NULL, XNAME, "rxintr");
574 1.2.18.2 yamt evcnt_attach_dynamic(&sc->sc_txqe, EVCNT_TYPE_MISC,
575 1.2.18.2 yamt NULL, XNAME, "txqe");
576 1.2.18.2 yamt #endif
577 1.2.18.2 yamt }
578 1.2.18.2 yamt
579 1.2.18.2 yamt void
580 1.2.18.2 yamt xge_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
581 1.2.18.2 yamt {
582 1.2.18.2 yamt struct xge_softc *sc = ifp->if_softc;
583 1.2.18.2 yamt uint64_t reg;
584 1.2.18.2 yamt
585 1.2.18.2 yamt ifmr->ifm_status = IFM_AVALID;
586 1.2.18.2 yamt ifmr->ifm_active = IFM_ETHER|IFM_10G_LR;
587 1.2.18.2 yamt
588 1.2.18.2 yamt reg = PIF_RCSR(ADAPTER_STATUS);
589 1.2.18.2 yamt if ((reg & (RMAC_REMOTE_FAULT|RMAC_LOCAL_FAULT)) == 0)
590 1.2.18.2 yamt ifmr->ifm_status |= IFM_ACTIVE;
591 1.2.18.2 yamt }
592 1.2.18.2 yamt
593 1.2.18.2 yamt int
594 1.2.18.2 yamt xge_xgmii_mediachange(struct ifnet *ifp)
595 1.2.18.2 yamt {
596 1.2.18.2 yamt return 0;
597 1.2.18.2 yamt }
598 1.2.18.2 yamt
599 1.2.18.2 yamt static void
600 1.2.18.2 yamt xge_enable(struct xge_softc *sc)
601 1.2.18.2 yamt {
602 1.2.18.2 yamt uint64_t val;
603 1.2.18.2 yamt
604 1.2.18.2 yamt /* 2, enable adapter */
605 1.2.18.2 yamt val = PIF_RCSR(ADAPTER_CONTROL);
606 1.2.18.2 yamt val |= ADAPTER_EN;
607 1.2.18.2 yamt PIF_WCSR(ADAPTER_CONTROL, val);
608 1.2.18.2 yamt
609 1.2.18.2 yamt /* 3, light the card enable led */
610 1.2.18.2 yamt val = PIF_RCSR(ADAPTER_CONTROL);
611 1.2.18.2 yamt val |= LED_ON;
612 1.2.18.2 yamt PIF_WCSR(ADAPTER_CONTROL, val);
613 1.2.18.2 yamt printf("%s: link up\n", XNAME);
614 1.2.18.2 yamt
615 1.2.18.2 yamt }
616 1.2.18.2 yamt
617 1.2.18.2 yamt int
618 1.2.18.2 yamt xge_init(struct ifnet *ifp)
619 1.2.18.2 yamt {
620 1.2.18.2 yamt struct xge_softc *sc = ifp->if_softc;
621 1.2.18.2 yamt uint64_t val;
622 1.2.18.2 yamt
623 1.2.18.2 yamt if (ifp->if_flags & IFF_RUNNING)
624 1.2.18.2 yamt return 0;
625 1.2.18.2 yamt
626 1.2.18.2 yamt /* 31+32, setup MAC config */
627 1.2.18.2 yamt PIF_WKEY(MAC_CFG, TMAC_EN|RMAC_EN|TMAC_APPEND_PAD|RMAC_STRIP_FCS|
628 1.2.18.2 yamt RMAC_BCAST_EN|RMAC_DISCARD_PFRM|RMAC_PROM_EN);
629 1.2.18.2 yamt
630 1.2.18.2 yamt DELAY(1000);
631 1.2.18.2 yamt
632 1.2.18.2 yamt /* 54, ensure that the adapter is 'quiescent' */
633 1.2.18.2 yamt val = PIF_RCSR(ADAPTER_STATUS);
634 1.2.18.2 yamt if ((val & QUIESCENT) != QUIESCENT) {
635 1.2.18.2 yamt char buf[200];
636 1.2.18.2 yamt printf("%s: adapter not quiescent, aborting\n", XNAME);
637 1.2.18.2 yamt val = (val & QUIESCENT) ^ QUIESCENT;
638 1.2.18.2 yamt bitmask_snprintf(val, QUIESCENT_BMSK, buf, sizeof buf);
639 1.2.18.2 yamt printf("%s: ADAPTER_STATUS missing bits %s\n", XNAME, buf);
640 1.2.18.2 yamt return 1;
641 1.2.18.2 yamt }
642 1.2.18.2 yamt
643 1.2.18.2 yamt /* 56, enable the transmit laser */
644 1.2.18.2 yamt val = PIF_RCSR(ADAPTER_CONTROL);
645 1.2.18.2 yamt val |= EOI_TX_ON;
646 1.2.18.2 yamt PIF_WCSR(ADAPTER_CONTROL, val);
647 1.2.18.2 yamt
648 1.2.18.2 yamt xge_enable(sc);
649 1.2.18.2 yamt /*
650 1.2.18.2 yamt * Enable all interrupts
651 1.2.18.2 yamt */
652 1.2.18.2 yamt PIF_WCSR(TX_TRAFFIC_MASK, 0);
653 1.2.18.2 yamt PIF_WCSR(RX_TRAFFIC_MASK, 0);
654 1.2.18.2 yamt PIF_WCSR(GENERAL_INT_MASK, 0);
655 1.2.18.2 yamt PIF_WCSR(TXPIC_INT_MASK, 0);
656 1.2.18.2 yamt PIF_WCSR(RXPIC_INT_MASK, 0);
657 1.2.18.2 yamt PIF_WCSR(MAC_INT_MASK, MAC_TMAC_INT); /* only from RMAC */
658 1.2.18.2 yamt PIF_WCSR(MAC_RMAC_ERR_MASK, ~RMAC_LINK_STATE_CHANGE_INT);
659 1.2.18.2 yamt
660 1.2.18.2 yamt
661 1.2.18.2 yamt /* Done... */
662 1.2.18.2 yamt ifp->if_flags |= IFF_RUNNING;
663 1.2.18.2 yamt ifp->if_flags &= ~IFF_OACTIVE;
664 1.2.18.2 yamt
665 1.2.18.2 yamt return 0;
666 1.2.18.2 yamt }
667 1.2.18.2 yamt
668 1.2.18.2 yamt static void
669 1.2.18.2 yamt xge_stop(struct ifnet *ifp, int disable)
670 1.2.18.2 yamt {
671 1.2.18.2 yamt struct xge_softc *sc = ifp->if_softc;
672 1.2.18.2 yamt uint64_t val;
673 1.2.18.2 yamt
674 1.2.18.2 yamt val = PIF_RCSR(ADAPTER_CONTROL);
675 1.2.18.2 yamt val &= ~ADAPTER_EN;
676 1.2.18.2 yamt PIF_WCSR(ADAPTER_CONTROL, val);
677 1.2.18.2 yamt
678 1.2.18.2 yamt while ((PIF_RCSR(ADAPTER_STATUS) & QUIESCENT) != QUIESCENT)
679 1.2.18.2 yamt ;
680 1.2.18.2 yamt }
681 1.2.18.2 yamt
682 1.2.18.2 yamt int
683 1.2.18.2 yamt xge_intr(void *pv)
684 1.2.18.2 yamt {
685 1.2.18.2 yamt struct xge_softc *sc = pv;
686 1.2.18.2 yamt struct txd *txd;
687 1.2.18.2 yamt struct ifnet *ifp = &sc->sc_if;
688 1.2.18.2 yamt bus_dmamap_t dmp;
689 1.2.18.2 yamt uint64_t val;
690 1.2.18.2 yamt int i, lasttx, plen;
691 1.2.18.2 yamt
692 1.2.18.2 yamt val = PIF_RCSR(GENERAL_INT_STATUS);
693 1.2.18.2 yamt if (val == 0)
694 1.2.18.2 yamt return 0; /* no interrupt here */
695 1.2.18.2 yamt
696 1.2.18.2 yamt XGE_EVCNT_INCR(&sc->sc_intr);
697 1.2.18.2 yamt
698 1.2.18.2 yamt PIF_WCSR(GENERAL_INT_STATUS, val);
699 1.2.18.2 yamt
700 1.2.18.2 yamt if ((val = PIF_RCSR(MAC_RMAC_ERR_REG)) & RMAC_LINK_STATE_CHANGE_INT) {
701 1.2.18.2 yamt /* Wait for quiescence */
702 1.2.18.2 yamt printf("%s: link down\n", XNAME);
703 1.2.18.2 yamt while ((PIF_RCSR(ADAPTER_STATUS) & QUIESCENT) != QUIESCENT)
704 1.2.18.2 yamt ;
705 1.2.18.2 yamt PIF_WCSR(MAC_RMAC_ERR_REG, RMAC_LINK_STATE_CHANGE_INT);
706 1.2.18.2 yamt
707 1.2.18.2 yamt val = PIF_RCSR(ADAPTER_STATUS);
708 1.2.18.2 yamt if ((val & (RMAC_REMOTE_FAULT|RMAC_LOCAL_FAULT)) == 0)
709 1.2.18.2 yamt xge_enable(sc); /* Only if link restored */
710 1.2.18.2 yamt }
711 1.2.18.2 yamt
712 1.2.18.2 yamt if ((val = PIF_RCSR(TX_TRAFFIC_INT))) {
713 1.2.18.2 yamt XGE_EVCNT_INCR(&sc->sc_txintr);
714 1.2.18.2 yamt PIF_WCSR(TX_TRAFFIC_INT, val); /* clear interrupt bits */
715 1.2.18.2 yamt }
716 1.2.18.2 yamt /*
717 1.2.18.2 yamt * Collect sent packets.
718 1.2.18.2 yamt */
719 1.2.18.2 yamt lasttx = sc->sc_lasttx;
720 1.2.18.2 yamt while ((i = NEXTTX(sc->sc_lasttx)) != sc->sc_nexttx) {
721 1.2.18.2 yamt txd = sc->sc_txd[i];
722 1.2.18.2 yamt dmp = sc->sc_txm[i];
723 1.2.18.2 yamt
724 1.2.18.2 yamt bus_dmamap_sync(sc->sc_dmat, dmp, 0,
725 1.2.18.2 yamt dmp->dm_mapsize,
726 1.2.18.2 yamt BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
727 1.2.18.2 yamt
728 1.2.18.2 yamt if (txd->txd_control1 & TXD_CTL1_OWN) {
729 1.2.18.2 yamt bus_dmamap_sync(sc->sc_dmat, dmp, 0,
730 1.2.18.2 yamt dmp->dm_mapsize, BUS_DMASYNC_PREREAD);
731 1.2.18.2 yamt break;
732 1.2.18.2 yamt }
733 1.2.18.2 yamt bus_dmamap_unload(sc->sc_dmat, dmp);
734 1.2.18.2 yamt m_freem(sc->sc_txb[i]);
735 1.2.18.2 yamt ifp->if_opackets++;
736 1.2.18.2 yamt sc->sc_lasttx = i;
737 1.2.18.2 yamt }
738 1.2.18.2 yamt if (i == sc->sc_nexttx) {
739 1.2.18.2 yamt XGE_EVCNT_INCR(&sc->sc_txqe);
740 1.2.18.2 yamt }
741 1.2.18.2 yamt
742 1.2.18.2 yamt if (sc->sc_lasttx != lasttx)
743 1.2.18.2 yamt ifp->if_flags &= ~IFF_OACTIVE;
744 1.2.18.2 yamt
745 1.2.18.2 yamt xge_start(ifp); /* Try to get more packets on the wire */
746 1.2.18.2 yamt
747 1.2.18.2 yamt if ((val = PIF_RCSR(RX_TRAFFIC_INT))) {
748 1.2.18.2 yamt XGE_EVCNT_INCR(&sc->sc_rxintr);
749 1.2.18.2 yamt PIF_WCSR(RX_TRAFFIC_INT, val); /* clear interrupt bits */
750 1.2.18.2 yamt }
751 1.2.18.2 yamt
752 1.2.18.2 yamt for (;;) {
753 1.2.18.2 yamt struct rxdesc *rxd;
754 1.2.18.2 yamt struct mbuf *m;
755 1.2.18.2 yamt
756 1.2.18.2 yamt XGE_RXSYNC(sc->sc_nextrx,
757 1.2.18.2 yamt BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
758 1.2.18.2 yamt
759 1.2.18.2 yamt rxd = XGE_RXD(sc->sc_nextrx);
760 1.2.18.2 yamt if (rxd->rxd_control1 & RXD_CTL1_OWN) {
761 1.2.18.2 yamt XGE_RXSYNC(sc->sc_nextrx, BUS_DMASYNC_PREREAD);
762 1.2.18.2 yamt break;
763 1.2.18.2 yamt }
764 1.2.18.2 yamt
765 1.2.18.2 yamt /* got a packet */
766 1.2.18.2 yamt m = sc->sc_rxb[sc->sc_nextrx];
767 1.2.18.2 yamt #if RX_MODE == RX_MODE_1
768 1.2.18.2 yamt plen = m->m_len = RXD_CTL2_BUF0SIZ(rxd->rxd_control2);
769 1.2.18.2 yamt #elif RX_MODE == RX_MODE_3
770 1.2.18.2 yamt #error Fix rxmodes in xge_intr
771 1.2.18.2 yamt #elif RX_MODE == RX_MODE_5
772 1.2.18.2 yamt plen = m->m_len = RXD_CTL2_BUF0SIZ(rxd->rxd_control2);
773 1.2.18.2 yamt plen += m->m_next->m_len = RXD_CTL2_BUF1SIZ(rxd->rxd_control2);
774 1.2.18.2 yamt plen += m->m_next->m_next->m_len =
775 1.2.18.2 yamt RXD_CTL2_BUF2SIZ(rxd->rxd_control2);
776 1.2.18.2 yamt plen += m->m_next->m_next->m_next->m_len =
777 1.2.18.2 yamt RXD_CTL3_BUF3SIZ(rxd->rxd_control3);
778 1.2.18.2 yamt plen += m->m_next->m_next->m_next->m_next->m_len =
779 1.2.18.2 yamt RXD_CTL3_BUF4SIZ(rxd->rxd_control3);
780 1.2.18.2 yamt #endif
781 1.2.18.2 yamt m->m_pkthdr.rcvif = ifp;
782 1.2.18.2 yamt m->m_pkthdr.len = plen;
783 1.2.18.2 yamt
784 1.2.18.2 yamt val = rxd->rxd_control1;
785 1.2.18.2 yamt
786 1.2.18.2 yamt if (xge_add_rxbuf(sc, sc->sc_nextrx)) {
787 1.2.18.2 yamt /* Failed, recycle this mbuf */
788 1.2.18.2 yamt #if RX_MODE == RX_MODE_1
789 1.2.18.2 yamt rxd->rxd_control2 = RXD_MKCTL2(MCLBYTES, 0, 0);
790 1.2.18.2 yamt rxd->rxd_control1 = RXD_CTL1_OWN;
791 1.2.18.2 yamt #elif RX_MODE == RX_MODE_3
792 1.2.18.2 yamt #elif RX_MODE == RX_MODE_5
793 1.2.18.2 yamt #endif
794 1.2.18.2 yamt XGE_RXSYNC(sc->sc_nextrx,
795 1.2.18.2 yamt BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
796 1.2.18.2 yamt ifp->if_ierrors++;
797 1.2.18.2 yamt break;
798 1.2.18.2 yamt }
799 1.2.18.2 yamt
800 1.2.18.2 yamt ifp->if_ipackets++;
801 1.2.18.2 yamt
802 1.2.18.2 yamt if (RXD_CTL1_PROTOS(val) & (RXD_CTL1_P_IPv4|RXD_CTL1_P_IPv6)) {
803 1.2.18.2 yamt m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
804 1.2.18.2 yamt if (RXD_CTL1_L3CSUM(val) != 0xffff)
805 1.2.18.2 yamt m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
806 1.2.18.2 yamt }
807 1.2.18.2 yamt if (RXD_CTL1_PROTOS(val) & RXD_CTL1_P_TCP) {
808 1.2.18.2 yamt m->m_pkthdr.csum_flags |= M_CSUM_TCPv4|M_CSUM_TCPv6;
809 1.2.18.2 yamt if (RXD_CTL1_L4CSUM(val) != 0xffff)
810 1.2.18.2 yamt m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
811 1.2.18.2 yamt }
812 1.2.18.2 yamt if (RXD_CTL1_PROTOS(val) & RXD_CTL1_P_UDP) {
813 1.2.18.2 yamt m->m_pkthdr.csum_flags |= M_CSUM_UDPv4|M_CSUM_UDPv6;
814 1.2.18.2 yamt if (RXD_CTL1_L4CSUM(val) != 0xffff)
815 1.2.18.2 yamt m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
816 1.2.18.2 yamt }
817 1.2.18.2 yamt
818 1.2.18.2 yamt #if NBPFILTER > 0
819 1.2.18.2 yamt if (ifp->if_bpf)
820 1.2.18.2 yamt bpf_mtap(ifp->if_bpf, m);
821 1.2.18.2 yamt #endif /* NBPFILTER > 0 */
822 1.2.18.2 yamt
823 1.2.18.2 yamt (*ifp->if_input)(ifp, m);
824 1.2.18.2 yamt
825 1.2.18.2 yamt if (++sc->sc_nextrx == NRXREAL)
826 1.2.18.2 yamt sc->sc_nextrx = 0;
827 1.2.18.2 yamt
828 1.2.18.2 yamt }
829 1.2.18.2 yamt
830 1.2.18.2 yamt return 0;
831 1.2.18.2 yamt }
832 1.2.18.2 yamt
833 1.2.18.2 yamt int
834 1.2.18.2 yamt xge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
835 1.2.18.2 yamt {
836 1.2.18.2 yamt struct xge_softc *sc = ifp->if_softc;
837 1.2.18.2 yamt struct ifreq *ifr = (struct ifreq *) data;
838 1.2.18.2 yamt int s, error = 0;
839 1.2.18.2 yamt
840 1.2.18.2 yamt s = splnet();
841 1.2.18.2 yamt
842 1.2.18.2 yamt switch (cmd) {
843 1.2.18.2 yamt case SIOCSIFMTU:
844 1.2.18.2 yamt if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > XGE_MAX_MTU) {
845 1.2.18.2 yamt error = EINVAL;
846 1.2.18.2 yamt } else {
847 1.2.18.2 yamt PIF_WCSR(RMAC_MAX_PYLD_LEN,
848 1.2.18.2 yamt RMAC_PYLD_LEN(ifr->ifr_mtu));
849 1.2.18.2 yamt ifp->if_mtu = ifr->ifr_mtu;
850 1.2.18.2 yamt }
851 1.2.18.2 yamt break;
852 1.2.18.2 yamt
853 1.2.18.2 yamt case SIOCGIFMEDIA:
854 1.2.18.2 yamt case SIOCSIFMEDIA:
855 1.2.18.2 yamt error = ifmedia_ioctl(ifp, ifr, &sc->xena_media, cmd);
856 1.2.18.2 yamt break;
857 1.2.18.2 yamt
858 1.2.18.2 yamt default:
859 1.2.18.2 yamt if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET){
860 1.2.18.2 yamt /* Change multicast list */
861 1.2.18.2 yamt xge_mcast_filter(sc);
862 1.2.18.2 yamt error = 0;
863 1.2.18.2 yamt }
864 1.2.18.2 yamt break;
865 1.2.18.2 yamt }
866 1.2.18.2 yamt
867 1.2.18.2 yamt splx(s);
868 1.2.18.2 yamt return(error);
869 1.2.18.2 yamt }
870 1.2.18.2 yamt
871 1.2.18.2 yamt void
872 1.2.18.2 yamt xge_mcast_filter(struct xge_softc *sc)
873 1.2.18.2 yamt {
874 1.2.18.2 yamt struct ifnet *ifp = &sc->sc_ethercom.ec_if;
875 1.2.18.2 yamt struct ethercom *ec = &sc->sc_ethercom;
876 1.2.18.2 yamt struct ether_multi *enm;
877 1.2.18.2 yamt struct ether_multistep step;
878 1.2.18.2 yamt int i, numaddr = 1; /* first slot used for card unicast address */
879 1.2.18.2 yamt uint64_t val;
880 1.2.18.2 yamt
881 1.2.18.2 yamt ETHER_FIRST_MULTI(step, ec, enm);
882 1.2.18.2 yamt while (enm != NULL) {
883 1.2.18.2 yamt if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
884 1.2.18.2 yamt /* Skip ranges */
885 1.2.18.2 yamt goto allmulti;
886 1.2.18.2 yamt }
887 1.2.18.2 yamt if (numaddr == MAX_MCAST_ADDR)
888 1.2.18.2 yamt goto allmulti;
889 1.2.18.2 yamt for (val = 0, i = 0; i < ETHER_ADDR_LEN; i++) {
890 1.2.18.2 yamt val <<= 8;
891 1.2.18.2 yamt val |= enm->enm_addrlo[i];
892 1.2.18.2 yamt }
893 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_DATA0_MEM, val << 16);
894 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_DATA1_MEM, 0xFFFFFFFFFFFFFFFFULL);
895 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_CMD_MEM, RMAC_ADDR_CMD_MEM_WE|
896 1.2.18.2 yamt RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(numaddr));
897 1.2.18.2 yamt while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
898 1.2.18.2 yamt ;
899 1.2.18.2 yamt numaddr++;
900 1.2.18.2 yamt ETHER_NEXT_MULTI(step, enm);
901 1.2.18.2 yamt }
902 1.2.18.2 yamt /* set the remaining entries to the broadcast address */
903 1.2.18.2 yamt for (i = numaddr; i < MAX_MCAST_ADDR; i++) {
904 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_DATA0_MEM, 0xffffffffffff0000ULL);
905 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_DATA1_MEM, 0xFFFFFFFFFFFFFFFFULL);
906 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_CMD_MEM, RMAC_ADDR_CMD_MEM_WE|
907 1.2.18.2 yamt RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(i));
908 1.2.18.2 yamt while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
909 1.2.18.2 yamt ;
910 1.2.18.2 yamt }
911 1.2.18.2 yamt ifp->if_flags &= ~IFF_ALLMULTI;
912 1.2.18.2 yamt return;
913 1.2.18.2 yamt
914 1.2.18.2 yamt allmulti:
915 1.2.18.2 yamt /* Just receive everything with the multicast bit set */
916 1.2.18.2 yamt ifp->if_flags |= IFF_ALLMULTI;
917 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_DATA0_MEM, 0x8000000000000000ULL);
918 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_DATA1_MEM, 0xF000000000000000ULL);
919 1.2.18.2 yamt PIF_WCSR(RMAC_ADDR_CMD_MEM, RMAC_ADDR_CMD_MEM_WE|
920 1.2.18.2 yamt RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(1));
921 1.2.18.2 yamt while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
922 1.2.18.2 yamt ;
923 1.2.18.2 yamt }
924 1.2.18.2 yamt
925 1.2.18.2 yamt void
926 1.2.18.2 yamt xge_start(struct ifnet *ifp)
927 1.2.18.2 yamt {
928 1.2.18.2 yamt struct xge_softc *sc = ifp->if_softc;
929 1.2.18.2 yamt struct txd *txd = NULL; /* XXX - gcc */
930 1.2.18.2 yamt bus_dmamap_t dmp;
931 1.2.18.2 yamt struct mbuf *m;
932 1.2.18.2 yamt uint64_t par, lcr;
933 1.2.18.2 yamt int nexttx = 0, ntxd, error, i;
934 1.2.18.2 yamt
935 1.2.18.2 yamt if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
936 1.2.18.2 yamt return;
937 1.2.18.2 yamt
938 1.2.18.2 yamt par = lcr = 0;
939 1.2.18.2 yamt for (;;) {
940 1.2.18.2 yamt IFQ_POLL(&ifp->if_snd, m);
941 1.2.18.2 yamt if (m == NULL)
942 1.2.18.2 yamt break; /* out of packets */
943 1.2.18.2 yamt
944 1.2.18.2 yamt if (sc->sc_nexttx == sc->sc_lasttx)
945 1.2.18.2 yamt break; /* No more space */
946 1.2.18.2 yamt
947 1.2.18.2 yamt nexttx = sc->sc_nexttx;
948 1.2.18.2 yamt dmp = sc->sc_txm[nexttx];
949 1.2.18.2 yamt
950 1.2.18.2 yamt if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmp, m,
951 1.2.18.2 yamt BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0) {
952 1.2.18.2 yamt printf("%s: bus_dmamap_load_mbuf error %d\n",
953 1.2.18.2 yamt XNAME, error);
954 1.2.18.2 yamt break;
955 1.2.18.2 yamt }
956 1.2.18.2 yamt IFQ_DEQUEUE(&ifp->if_snd, m);
957 1.2.18.2 yamt
958 1.2.18.2 yamt bus_dmamap_sync(sc->sc_dmat, dmp, 0, dmp->dm_mapsize,
959 1.2.18.2 yamt BUS_DMASYNC_PREWRITE);
960 1.2.18.2 yamt
961 1.2.18.2 yamt txd = sc->sc_txd[nexttx];
962 1.2.18.2 yamt sc->sc_txb[nexttx] = m;
963 1.2.18.2 yamt for (i = 0; i < dmp->dm_nsegs; i++) {
964 1.2.18.2 yamt if (dmp->dm_segs[i].ds_len == 0)
965 1.2.18.2 yamt continue;
966 1.2.18.2 yamt txd->txd_control1 = dmp->dm_segs[i].ds_len;
967 1.2.18.2 yamt txd->txd_control2 = 0;
968 1.2.18.2 yamt txd->txd_bufaddr = dmp->dm_segs[i].ds_addr;
969 1.2.18.2 yamt txd++;
970 1.2.18.2 yamt }
971 1.2.18.2 yamt ntxd = txd - sc->sc_txd[nexttx] - 1;
972 1.2.18.2 yamt txd = sc->sc_txd[nexttx];
973 1.2.18.2 yamt txd->txd_control1 |= TXD_CTL1_OWN|TXD_CTL1_GCF;
974 1.2.18.2 yamt txd->txd_control2 = TXD_CTL2_UTIL;
975 1.2.18.2 yamt if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) {
976 1.2.18.2 yamt txd->txd_control1 |= TXD_CTL1_MSS(m->m_pkthdr.segsz);
977 1.2.18.2 yamt txd->txd_control1 |= TXD_CTL1_LSO;
978 1.2.18.2 yamt }
979 1.2.18.2 yamt
980 1.2.18.2 yamt if (m->m_pkthdr.csum_flags & M_CSUM_IPv4)
981 1.2.18.2 yamt txd->txd_control2 |= TXD_CTL2_CIPv4;
982 1.2.18.2 yamt if (m->m_pkthdr.csum_flags & M_CSUM_TCPv4)
983 1.2.18.2 yamt txd->txd_control2 |= TXD_CTL2_CTCP;
984 1.2.18.2 yamt if (m->m_pkthdr.csum_flags & M_CSUM_UDPv4)
985 1.2.18.2 yamt txd->txd_control2 |= TXD_CTL2_CUDP;
986 1.2.18.2 yamt txd[ntxd].txd_control1 |= TXD_CTL1_GCL;
987 1.2.18.2 yamt
988 1.2.18.2 yamt bus_dmamap_sync(sc->sc_dmat, dmp, 0, dmp->dm_mapsize,
989 1.2.18.2 yamt BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
990 1.2.18.2 yamt
991 1.2.18.2 yamt par = sc->sc_txdp[nexttx];
992 1.2.18.2 yamt lcr = TXDL_NUMTXD(ntxd) | TXDL_LGC_FIRST | TXDL_LGC_LAST;
993 1.2.18.2 yamt if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4)
994 1.2.18.2 yamt lcr |= TXDL_SFF;
995 1.2.18.2 yamt TXP_WCSR(TXDL_PAR, par);
996 1.2.18.2 yamt TXP_WCSR(TXDL_LCR, lcr);
997 1.2.18.2 yamt
998 1.2.18.2 yamt #if NBPFILTER > 0
999 1.2.18.2 yamt if (ifp->if_bpf)
1000 1.2.18.2 yamt bpf_mtap(ifp->if_bpf, m);
1001 1.2.18.2 yamt #endif /* NBPFILTER > 0 */
1002 1.2.18.2 yamt
1003 1.2.18.2 yamt sc->sc_nexttx = NEXTTX(nexttx);
1004 1.2.18.2 yamt }
1005 1.2.18.2 yamt }
1006 1.2.18.2 yamt
1007 1.2.18.2 yamt /*
1008 1.2.18.2 yamt * Allocate DMA memory for transmit descriptor fragments.
1009 1.2.18.2 yamt * Only one map is used for all descriptors.
1010 1.2.18.2 yamt */
1011 1.2.18.2 yamt int
1012 1.2.18.2 yamt xge_alloc_txmem(struct xge_softc *sc)
1013 1.2.18.2 yamt {
1014 1.2.18.2 yamt struct txd *txp;
1015 1.2.18.2 yamt bus_dma_segment_t seg;
1016 1.2.18.2 yamt bus_addr_t txdp;
1017 1.2.18.2 yamt caddr_t kva;
1018 1.2.18.2 yamt int i, rseg, state;
1019 1.2.18.2 yamt
1020 1.2.18.2 yamt #define TXMAPSZ (NTXDESCS*NTXFRAGS*sizeof(struct txd))
1021 1.2.18.2 yamt state = 0;
1022 1.2.18.2 yamt if (bus_dmamem_alloc(sc->sc_dmat, TXMAPSZ, PAGE_SIZE, 0,
1023 1.2.18.2 yamt &seg, 1, &rseg, BUS_DMA_NOWAIT))
1024 1.2.18.2 yamt goto err;
1025 1.2.18.2 yamt state++;
1026 1.2.18.2 yamt if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, TXMAPSZ, &kva,
1027 1.2.18.2 yamt BUS_DMA_NOWAIT))
1028 1.2.18.2 yamt goto err;
1029 1.2.18.2 yamt
1030 1.2.18.2 yamt state++;
1031 1.2.18.2 yamt if (bus_dmamap_create(sc->sc_dmat, TXMAPSZ, 1, TXMAPSZ, 0,
1032 1.2.18.2 yamt BUS_DMA_NOWAIT, &sc->sc_txmap))
1033 1.2.18.2 yamt goto err;
1034 1.2.18.2 yamt state++;
1035 1.2.18.2 yamt if (bus_dmamap_load(sc->sc_dmat, sc->sc_txmap,
1036 1.2.18.2 yamt kva, TXMAPSZ, NULL, BUS_DMA_NOWAIT))
1037 1.2.18.2 yamt goto err;
1038 1.2.18.2 yamt
1039 1.2.18.2 yamt /* setup transmit array pointers */
1040 1.2.18.2 yamt txp = (struct txd *)kva;
1041 1.2.18.2 yamt txdp = seg.ds_addr;
1042 1.2.18.2 yamt for (txp = (struct txd *)kva, i = 0; i < NTXDESCS; i++) {
1043 1.2.18.2 yamt sc->sc_txd[i] = txp;
1044 1.2.18.2 yamt sc->sc_txdp[i] = txdp;
1045 1.2.18.2 yamt txp += NTXFRAGS;
1046 1.2.18.2 yamt txdp += (NTXFRAGS * sizeof(struct txd));
1047 1.2.18.2 yamt }
1048 1.2.18.2 yamt
1049 1.2.18.2 yamt return 0;
1050 1.2.18.2 yamt
1051 1.2.18.2 yamt err:
1052 1.2.18.2 yamt if (state > 2)
1053 1.2.18.2 yamt bus_dmamap_destroy(sc->sc_dmat, sc->sc_txmap);
1054 1.2.18.2 yamt if (state > 1)
1055 1.2.18.2 yamt bus_dmamem_unmap(sc->sc_dmat, kva, TXMAPSZ);
1056 1.2.18.2 yamt if (state > 0)
1057 1.2.18.2 yamt bus_dmamem_free(sc->sc_dmat, &seg, rseg);
1058 1.2.18.2 yamt return ENOBUFS;
1059 1.2.18.2 yamt }
1060 1.2.18.2 yamt
1061 1.2.18.2 yamt /*
1062 1.2.18.2 yamt * Allocate DMA memory for receive descriptor,
1063 1.2.18.2 yamt * only one map is used for all descriptors.
1064 1.2.18.2 yamt * link receive descriptor pages together.
1065 1.2.18.2 yamt */
1066 1.2.18.2 yamt int
1067 1.2.18.2 yamt xge_alloc_rxmem(struct xge_softc *sc)
1068 1.2.18.2 yamt {
1069 1.2.18.2 yamt struct rxd_4k *rxpp;
1070 1.2.18.2 yamt bus_dma_segment_t seg;
1071 1.2.18.2 yamt caddr_t kva;
1072 1.2.18.2 yamt int i, rseg, state;
1073 1.2.18.2 yamt
1074 1.2.18.2 yamt /* sanity check */
1075 1.2.18.2 yamt if (sizeof(struct rxd_4k) != XGE_PAGE) {
1076 1.2.18.2 yamt printf("bad compiler struct alignment, %d != %d\n",
1077 1.2.18.2 yamt (int)sizeof(struct rxd_4k), XGE_PAGE);
1078 1.2.18.2 yamt return EINVAL;
1079 1.2.18.2 yamt }
1080 1.2.18.2 yamt
1081 1.2.18.2 yamt state = 0;
1082 1.2.18.2 yamt if (bus_dmamem_alloc(sc->sc_dmat, RXMAPSZ, PAGE_SIZE, 0,
1083 1.2.18.2 yamt &seg, 1, &rseg, BUS_DMA_NOWAIT))
1084 1.2.18.2 yamt goto err;
1085 1.2.18.2 yamt state++;
1086 1.2.18.2 yamt if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, RXMAPSZ, &kva,
1087 1.2.18.2 yamt BUS_DMA_NOWAIT))
1088 1.2.18.2 yamt goto err;
1089 1.2.18.2 yamt
1090 1.2.18.2 yamt state++;
1091 1.2.18.2 yamt if (bus_dmamap_create(sc->sc_dmat, RXMAPSZ, 1, RXMAPSZ, 0,
1092 1.2.18.2 yamt BUS_DMA_NOWAIT, &sc->sc_rxmap))
1093 1.2.18.2 yamt goto err;
1094 1.2.18.2 yamt state++;
1095 1.2.18.2 yamt if (bus_dmamap_load(sc->sc_dmat, sc->sc_rxmap,
1096 1.2.18.2 yamt kva, RXMAPSZ, NULL, BUS_DMA_NOWAIT))
1097 1.2.18.2 yamt goto err;
1098 1.2.18.2 yamt
1099 1.2.18.2 yamt /* setup receive page link pointers */
1100 1.2.18.2 yamt for (rxpp = (struct rxd_4k *)kva, i = 0; i < NRXPAGES; i++, rxpp++) {
1101 1.2.18.2 yamt sc->sc_rxd_4k[i] = rxpp;
1102 1.2.18.2 yamt rxpp->r4_next = (uint64_t)sc->sc_rxmap->dm_segs[0].ds_addr +
1103 1.2.18.2 yamt (i*sizeof(struct rxd_4k)) + sizeof(struct rxd_4k);
1104 1.2.18.2 yamt }
1105 1.2.18.2 yamt sc->sc_rxd_4k[NRXPAGES-1]->r4_next =
1106 1.2.18.2 yamt (uint64_t)sc->sc_rxmap->dm_segs[0].ds_addr;
1107 1.2.18.2 yamt
1108 1.2.18.2 yamt return 0;
1109 1.2.18.2 yamt
1110 1.2.18.2 yamt err:
1111 1.2.18.2 yamt if (state > 2)
1112 1.2.18.2 yamt bus_dmamap_destroy(sc->sc_dmat, sc->sc_txmap);
1113 1.2.18.2 yamt if (state > 1)
1114 1.2.18.2 yamt bus_dmamem_unmap(sc->sc_dmat, kva, TXMAPSZ);
1115 1.2.18.2 yamt if (state > 0)
1116 1.2.18.2 yamt bus_dmamem_free(sc->sc_dmat, &seg, rseg);
1117 1.2.18.2 yamt return ENOBUFS;
1118 1.2.18.2 yamt }
1119 1.2.18.2 yamt
1120 1.2.18.2 yamt
1121 1.2.18.2 yamt /*
1122 1.2.18.2 yamt * Add a new mbuf chain to descriptor id.
1123 1.2.18.2 yamt */
1124 1.2.18.2 yamt int
1125 1.2.18.2 yamt xge_add_rxbuf(struct xge_softc *sc, int id)
1126 1.2.18.2 yamt {
1127 1.2.18.2 yamt struct rxdesc *rxd;
1128 1.2.18.2 yamt struct mbuf *m[5];
1129 1.2.18.2 yamt int page, desc, error;
1130 1.2.18.2 yamt #if RX_MODE == RX_MODE_5
1131 1.2.18.2 yamt int i;
1132 1.2.18.2 yamt #endif
1133 1.2.18.2 yamt
1134 1.2.18.2 yamt page = id/NDESC_BUFMODE;
1135 1.2.18.2 yamt desc = id%NDESC_BUFMODE;
1136 1.2.18.2 yamt
1137 1.2.18.2 yamt rxd = &sc->sc_rxd_4k[page]->r4_rxd[desc];
1138 1.2.18.2 yamt
1139 1.2.18.2 yamt /*
1140 1.2.18.2 yamt * Allocate mbufs.
1141 1.2.18.2 yamt * Currently five mbufs and two clusters are used,
1142 1.2.18.2 yamt * the hardware will put (ethernet, ip, tcp/udp) headers in
1143 1.2.18.2 yamt * their own buffer and the clusters are only used for data.
1144 1.2.18.2 yamt */
1145 1.2.18.2 yamt #if RX_MODE == RX_MODE_1
1146 1.2.18.2 yamt MGETHDR(m[0], M_DONTWAIT, MT_DATA);
1147 1.2.18.2 yamt if (m[0] == NULL)
1148 1.2.18.2 yamt return ENOBUFS;
1149 1.2.18.2 yamt MCLGET(m[0], M_DONTWAIT);
1150 1.2.18.2 yamt if ((m[0]->m_flags & M_EXT) == 0) {
1151 1.2.18.2 yamt m_freem(m[0]);
1152 1.2.18.2 yamt return ENOBUFS;
1153 1.2.18.2 yamt }
1154 1.2.18.2 yamt m[0]->m_len = m[0]->m_pkthdr.len = m[0]->m_ext.ext_size;
1155 1.2.18.2 yamt #elif RX_MODE == RX_MODE_3
1156 1.2.18.2 yamt #error missing rxmode 3.
1157 1.2.18.2 yamt #elif RX_MODE == RX_MODE_5
1158 1.2.18.2 yamt MGETHDR(m[0], M_DONTWAIT, MT_DATA);
1159 1.2.18.2 yamt for (i = 1; i < 5; i++) {
1160 1.2.18.2 yamt MGET(m[i], M_DONTWAIT, MT_DATA);
1161 1.2.18.2 yamt }
1162 1.2.18.2 yamt if (m[3])
1163 1.2.18.2 yamt MCLGET(m[3], M_DONTWAIT);
1164 1.2.18.2 yamt if (m[4])
1165 1.2.18.2 yamt MCLGET(m[4], M_DONTWAIT);
1166 1.2.18.2 yamt if (!m[0] || !m[1] || !m[2] || !m[3] || !m[4] ||
1167 1.2.18.2 yamt ((m[3]->m_flags & M_EXT) == 0) || ((m[4]->m_flags & M_EXT) == 0)) {
1168 1.2.18.2 yamt /* Out of something */
1169 1.2.18.2 yamt for (i = 0; i < 5; i++)
1170 1.2.18.2 yamt if (m[i] != NULL)
1171 1.2.18.2 yamt m_free(m[i]);
1172 1.2.18.2 yamt return ENOBUFS;
1173 1.2.18.2 yamt }
1174 1.2.18.2 yamt /* Link'em together */
1175 1.2.18.2 yamt m[0]->m_next = m[1];
1176 1.2.18.2 yamt m[1]->m_next = m[2];
1177 1.2.18.2 yamt m[2]->m_next = m[3];
1178 1.2.18.2 yamt m[3]->m_next = m[4];
1179 1.2.18.2 yamt #else
1180 1.2.18.2 yamt #error bad mode RX_MODE
1181 1.2.18.2 yamt #endif
1182 1.2.18.2 yamt
1183 1.2.18.2 yamt if (sc->sc_rxb[id])
1184 1.2.18.2 yamt bus_dmamap_unload(sc->sc_dmat, sc->sc_rxm[id]);
1185 1.2.18.2 yamt sc->sc_rxb[id] = m[0];
1186 1.2.18.2 yamt
1187 1.2.18.2 yamt error = bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rxm[id], m[0],
1188 1.2.18.2 yamt BUS_DMA_READ|BUS_DMA_NOWAIT);
1189 1.2.18.2 yamt if (error)
1190 1.2.18.2 yamt return error;
1191 1.2.18.2 yamt bus_dmamap_sync(sc->sc_dmat, sc->sc_rxm[id], 0,
1192 1.2.18.2 yamt sc->sc_rxm[id]->dm_mapsize, BUS_DMASYNC_PREREAD);
1193 1.2.18.2 yamt
1194 1.2.18.2 yamt #if RX_MODE == RX_MODE_1
1195 1.2.18.2 yamt rxd->rxd_control2 = RXD_MKCTL2(m[0]->m_len, 0, 0);
1196 1.2.18.2 yamt rxd->rxd_buf0 = (uint64_t)sc->sc_rxm[id]->dm_segs[0].ds_addr;
1197 1.2.18.2 yamt rxd->rxd_control1 = RXD_CTL1_OWN;
1198 1.2.18.2 yamt #elif RX_MODE == RX_MODE_3
1199 1.2.18.2 yamt #elif RX_MODE == RX_MODE_5
1200 1.2.18.2 yamt rxd->rxd_control3 = RXD_MKCTL3(0, m[3]->m_len, m[4]->m_len);
1201 1.2.18.2 yamt rxd->rxd_control2 = RXD_MKCTL2(m[0]->m_len, m[1]->m_len, m[2]->m_len);
1202 1.2.18.2 yamt rxd->rxd_buf0 = (uint64_t)sc->sc_rxm[id]->dm_segs[0].ds_addr;
1203 1.2.18.2 yamt rxd->rxd_buf1 = (uint64_t)sc->sc_rxm[id]->dm_segs[1].ds_addr;
1204 1.2.18.2 yamt rxd->rxd_buf2 = (uint64_t)sc->sc_rxm[id]->dm_segs[2].ds_addr;
1205 1.2.18.2 yamt rxd->rxd_buf3 = (uint64_t)sc->sc_rxm[id]->dm_segs[3].ds_addr;
1206 1.2.18.2 yamt rxd->rxd_buf4 = (uint64_t)sc->sc_rxm[id]->dm_segs[4].ds_addr;
1207 1.2.18.2 yamt rxd->rxd_control1 = RXD_CTL1_OWN;
1208 1.2.18.2 yamt #endif
1209 1.2.18.2 yamt
1210 1.2.18.2 yamt XGE_RXSYNC(id, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1211 1.2.18.2 yamt return 0;
1212 1.2.18.2 yamt }
1213 1.2.18.2 yamt
1214 1.2.18.2 yamt /*
1215 1.2.18.2 yamt * These magics comes from the FreeBSD driver.
1216 1.2.18.2 yamt */
1217 1.2.18.2 yamt int
1218 1.2.18.2 yamt xge_setup_xgxs(struct xge_softc *sc)
1219 1.2.18.2 yamt {
1220 1.2.18.2 yamt /* The magic numbers are described in the users guide */
1221 1.2.18.2 yamt
1222 1.2.18.2 yamt /* Writing to MDIO 0x8000 (Global Config 0) */
1223 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x8000051500000000ULL); DELAY(50);
1224 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80000515000000E0ULL); DELAY(50);
1225 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80000515D93500E4ULL); DELAY(50);
1226 1.2.18.2 yamt
1227 1.2.18.2 yamt /* Writing to MDIO 0x8000 (Global Config 1) */
1228 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x8001051500000000ULL); DELAY(50);
1229 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80010515000000e0ULL); DELAY(50);
1230 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80010515001e00e4ULL); DELAY(50);
1231 1.2.18.2 yamt
1232 1.2.18.2 yamt /* Reset the Gigablaze */
1233 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x8002051500000000ULL); DELAY(50);
1234 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80020515000000E0ULL); DELAY(50);
1235 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80020515F21000E4ULL); DELAY(50);
1236 1.2.18.2 yamt
1237 1.2.18.2 yamt /* read the pole settings */
1238 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x8000051500000000ULL); DELAY(50);
1239 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80000515000000e0ULL); DELAY(50);
1240 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80000515000000ecULL); DELAY(50);
1241 1.2.18.2 yamt
1242 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x8001051500000000ULL); DELAY(50);
1243 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80010515000000e0ULL); DELAY(50);
1244 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80010515000000ecULL); DELAY(50);
1245 1.2.18.2 yamt
1246 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x8002051500000000ULL); DELAY(50);
1247 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80020515000000e0ULL); DELAY(50);
1248 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x80020515000000ecULL); DELAY(50);
1249 1.2.18.2 yamt
1250 1.2.18.2 yamt /* Workaround for TX Lane XAUI initialization error.
1251 1.2.18.2 yamt Read Xpak PHY register 24 for XAUI lane status */
1252 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x0018040000000000ULL); DELAY(50);
1253 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x00180400000000e0ULL); DELAY(50);
1254 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x00180400000000ecULL); DELAY(50);
1255 1.2.18.2 yamt
1256 1.2.18.2 yamt /*
1257 1.2.18.2 yamt * Reading the MDIO control with value 0x1804001c0F001c
1258 1.2.18.2 yamt * means the TxLanes were already in sync
1259 1.2.18.2 yamt * Reading the MDIO control with value 0x1804000c0x001c
1260 1.2.18.2 yamt * means some TxLanes are not in sync where x is a 4-bit
1261 1.2.18.2 yamt * value representing each lanes
1262 1.2.18.2 yamt */
1263 1.2.18.2 yamt #if 0
1264 1.2.18.2 yamt val = PIF_RCSR(MDIO_CONTROL);
1265 1.2.18.2 yamt if (val != 0x1804001c0F001cULL) {
1266 1.2.18.2 yamt printf("%s: MDIO_CONTROL: %llx != %llx\n",
1267 1.2.18.2 yamt XNAME, val, 0x1804001c0F001cULL);
1268 1.2.18.2 yamt return 1;
1269 1.2.18.2 yamt }
1270 1.2.18.2 yamt #endif
1271 1.2.18.2 yamt
1272 1.2.18.2 yamt /* Set and remove the DTE XS INTLoopBackN */
1273 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x0000051500000000ULL); DELAY(50);
1274 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x00000515604000e0ULL); DELAY(50);
1275 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x00000515604000e4ULL); DELAY(50);
1276 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x00000515204000e4ULL); DELAY(50);
1277 1.2.18.2 yamt PIF_WCSR(DTX_CONTROL, 0x00000515204000ecULL); DELAY(50);
1278 1.2.18.2 yamt
1279 1.2.18.2 yamt #if 0
1280 1.2.18.2 yamt /* Reading the DTX control register Should be 0x5152040001c */
1281 1.2.18.2 yamt val = PIF_RCSR(DTX_CONTROL);
1282 1.2.18.2 yamt if (val != 0x5152040001cULL) {
1283 1.2.18.2 yamt printf("%s: DTX_CONTROL: %llx != %llx\n",
1284 1.2.18.2 yamt XNAME, val, 0x5152040001cULL);
1285 1.2.18.2 yamt return 1;
1286 1.2.18.2 yamt }
1287 1.2.18.2 yamt #endif
1288 1.2.18.2 yamt
1289 1.2.18.2 yamt PIF_WCSR(MDIO_CONTROL, 0x0018040000000000ULL); DELAY(50);
1290 1.2.18.2 yamt PIF_WCSR(MDIO_CONTROL, 0x00180400000000e0ULL); DELAY(50);
1291 1.2.18.2 yamt PIF_WCSR(MDIO_CONTROL, 0x00180400000000ecULL); DELAY(50);
1292 1.2.18.2 yamt
1293 1.2.18.2 yamt #if 0
1294 1.2.18.2 yamt /* Reading the MIOD control should be 0x1804001c0f001c */
1295 1.2.18.2 yamt val = PIF_RCSR(MDIO_CONTROL);
1296 1.2.18.2 yamt if (val != 0x1804001c0f001cULL) {
1297 1.2.18.2 yamt printf("%s: MDIO_CONTROL2: %llx != %llx\n",
1298 1.2.18.2 yamt XNAME, val, 0x1804001c0f001cULL);
1299 1.2.18.2 yamt return 1;
1300 1.2.18.2 yamt }
1301 1.2.18.2 yamt #endif
1302 1.2.18.2 yamt return 0;
1303 1.2.18.2 yamt }
1304