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