mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-05 09:14:03 +00:00
Add the initial version of if_nf10bmac(4), a driver to support an
NetFPGA-10G Embedded CPU Ethernet Core. The current version operates on a simple PIO based interface connected to a NetFPGA-10G port. To avoid confusion: this driver operates on a CPU running on the FPGA, e.g. BERI/mips, and is not suited for the PCI host interface. MFC after: 1 week Relnotes: yes Sponsored by: DARPA/AFRL
This commit is contained in:
parent
99143cd46c
commit
4a9af7d53f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=264601
@ -280,6 +280,7 @@ MAN= aac.4 \
|
||||
ncv.4 \
|
||||
${_ndis.4} \
|
||||
net80211.4 \
|
||||
netfpga10g_nf10bmac.4 \
|
||||
netgraph.4 \
|
||||
netintro.4 \
|
||||
netmap.4 \
|
||||
@ -675,6 +676,7 @@ MLINKS+=mwl.4 if_mwl.4
|
||||
MLINKS+=mxge.4 if_mxge.4
|
||||
MLINKS+=my.4 if_my.4
|
||||
MLINKS+=${_ndis.4} ${_if_ndis.4}
|
||||
MLINKS+=netfpga10g_nf10bmac.4 if_nf10bmac.4
|
||||
MLINKS+=netintro.4 net.4 \
|
||||
netintro.4 networking.4
|
||||
MLINKS+=${_nfe.4} ${_if_nfe.4}
|
||||
|
70
share/man/man4/netfpga10g_nf10bmac.4
Normal file
70
share/man/man4/netfpga10g_nf10bmac.4
Normal file
@ -0,0 +1,70 @@
|
||||
.\"-
|
||||
.\" Copyright (c) 2014 Bjoern A. Zeeb
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This software was developed by SRI International and the University of
|
||||
.\" Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||
.\" ("MRC2"), as part of the DARPA MRC research programme.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 17, 2014
|
||||
.Dt NETFPGA10G_NF10BMAC 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm netfpga10g_nf10bmac
|
||||
.Nd driver for the NetFPGA-10G Embedded CPU Ethernet Core
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device netfpga10g_nf10bmac"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
device driver provides support for the NetFPGA-10G Embedded CPU Ethernet
|
||||
Core.
|
||||
.Sh HARDWARE
|
||||
The current version of the
|
||||
.Nm
|
||||
driver works with one PIO mode interface of the
|
||||
NetFPGA-10G Embedded CPU Ethernet Core version 1.00a.
|
||||
.Sh SEE ALSO
|
||||
.Xr netintro 4 ,
|
||||
.Xr ifconfig 8
|
||||
.Rs
|
||||
.%T NetFPGA-10G Wiki
|
||||
.%U https://github.com/NetFPGA/NetFPGA-public/wiki
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
device driver first appeared in
|
||||
.Fx 11.0 .
|
||||
.Sh AUTHORS
|
||||
This software and this manual page were
|
||||
developed by SRI International and the University of Cambridge Computer
|
||||
Laboratory under DARPA/AFRL contract
|
||||
.Pq FA8750-11-C-0249
|
||||
.Pq Do MRC2 Dc ,
|
||||
as part of the DARPA MRC research programme.
|
||||
The device driver was written by
|
||||
.An Bjoern A. Zeeb .
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2012-2013 Robert N. M. Watson
|
||||
* Copyright (c) 2013 SRI International
|
||||
* Copyright (c) 2013 Bjoern A. Zeeb
|
||||
* Copyright (c) 2013-2014 Bjoern A. Zeeb
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
@ -132,6 +132,17 @@
|
||||
interrupt-parent = <&beripic>;
|
||||
};
|
||||
*/
|
||||
|
||||
ethernet@7f005000 {
|
||||
compatible = "netfpag10g,nf10bmac";
|
||||
// TX, RX, LOOP
|
||||
reg = <0x7f005010 0xc
|
||||
0x7f005020 0xc
|
||||
0x7f005030 0x4>;
|
||||
// RX
|
||||
#interrupts = <1>;
|
||||
#interrupt-parent = <&beripic>;
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
|
816
sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c
Normal file
816
sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c
Normal file
@ -0,0 +1,816 @@
|
||||
/*-
|
||||
* Copyright (c) 2012-2014 Bjoern A. Zeeb
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
* Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||
* ("MRC2"), as part of the DARPA MRC research programme.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This driver is modelled after atse(4). We need to seriously reduce the
|
||||
* per-driver code we have to write^wcopy & paste.
|
||||
*
|
||||
* TODO:
|
||||
* - figure out on the HW side why some data is LE and some is BE.
|
||||
* - general set of improvements possible (e.g., reduce times of copying,
|
||||
* do on-the-copy checksum calculations)
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_device_polling.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_vlan_var.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include "if_nf10bmacreg.h"
|
||||
|
||||
#ifndef NF10BMAC_MAX_PKTS
|
||||
/*
|
||||
* We have a 4k buffer in HW, so do not try to send more than 3 packets.
|
||||
* At the time of writing HW is orders of magnitude faster than we can
|
||||
* enqueue so it would not matter but need an escape.
|
||||
*/
|
||||
#define NF10BMAC_MAX_PKTS 3
|
||||
#endif
|
||||
|
||||
#ifndef NF10BMAC_WATCHDOG_TIME
|
||||
#define NF10BMAC_WATCHDOG_TIME 5 /* seconds */
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static poll_handler_t nf10bmac_poll;
|
||||
#endif
|
||||
|
||||
#define NF10BMAC_LOCK(_sc) mtx_lock(&(_sc)->nf10bmac_mtx)
|
||||
#define NF10BMAC_UNLOCK(_sc) mtx_unlock(&(_sc)->nf10bmac_mtx)
|
||||
#define NF10BMAC_LOCK_ASSERT(_sc) \
|
||||
mtx_assert(&(_sc)->nf10bmac_mtx, MA_OWNED)
|
||||
|
||||
#define NF10BMAC_TX_LEN 0x08
|
||||
#define NF10BMAC_TX_META 0x04
|
||||
#define NF10BMAC_TX_DATA 0x00
|
||||
#define NF10BMAC_RX_LEN 0x08
|
||||
#define NF10BMAC_RX_META 0x04
|
||||
#define NF10BMAC_RX_DATA 0x00
|
||||
#define NF10BMAC_CTRL0 0x00
|
||||
|
||||
#define NF10BMAC_TUSER_MAC0 (1 << 0)
|
||||
#define NF10BMAC_TUSER_CPU0 (1 << 1)
|
||||
#define NF10BMAC_TUSER_MAC1 (1 << 2)
|
||||
#define NF10BMAC_TUSER_CPU1 (1 << 3)
|
||||
#define NF10BMAC_TUSER_MAC2 (1 << 4)
|
||||
#define NF10BMAC_TUSER_CPU2 (1 << 5)
|
||||
#define NF10BMAC_TUSER_MAC3 (1 << 6)
|
||||
#define NF10BMAC_TUSER_CPU3 (1 << 7)
|
||||
|
||||
#define NF10BMAC_DATA_DPORT_MASK 0xff000000
|
||||
#define NF10BMAC_DATA_DPORT_SHIFT 24
|
||||
#define NF10BMAC_DATA_SPORT_MASK 0x00ff0000
|
||||
#define NF10BMAC_DATA_SPORT_SHIFT 16
|
||||
#define NF10BMAC_DATA_LAST 0x00000080
|
||||
#define NF10BMAC_DATA_STRB 0x0000000f
|
||||
|
||||
|
||||
static inline void
|
||||
nf10bmac_write_4(struct resource *res, uint32_t reg, uint32_t val4,
|
||||
const char *f __unused, const int l __unused)
|
||||
{
|
||||
|
||||
bus_write_4(res, reg, htole32(val4));
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
nf10bmac_read_4(struct resource *res, uint32_t reg,
|
||||
const char *f __unused, const int l __unused)
|
||||
{
|
||||
|
||||
return (le32toh(bus_read_4(res, reg)));
|
||||
}
|
||||
|
||||
static inline void
|
||||
nf10bmac_write_4_be(struct resource *res, uint32_t reg, uint32_t val4,
|
||||
const char *f __unused, const int l __unused)
|
||||
{
|
||||
|
||||
bus_write_4(res, reg, htobe32(val4));
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
nf10bmac_read_4_be(struct resource *res, uint32_t reg,
|
||||
const char *f __unused, const int l __unused)
|
||||
{
|
||||
|
||||
return (be32toh(bus_read_4(res, reg)));
|
||||
}
|
||||
|
||||
#define NF10BMAC_WRITE_CTRL_4(sc, reg, val) \
|
||||
nf10bmac_write_4((sc)->nf10bmac_mem_res, (reg), (val), \
|
||||
__func__, __LINE__)
|
||||
#define NF10BMAC_WRITE_4(sc, reg, val) \
|
||||
nf10bmac_write_4((sc)->nf10bmac_tx_mem_res, (reg), (val), \
|
||||
__func__, __LINE__)
|
||||
#define NF10BMAC_READ_4(sc, reg) \
|
||||
nf10bmac_read_4((sc)->nf10bmac_rx_mem_res, (reg), \
|
||||
__func__, __LINE__)
|
||||
#define NF10BMAC_WRITE_4_BE(sc, reg, val) \
|
||||
nf10bmac_write_4_be((sc)->nf10bmac_tx_mem_res, (reg), (val), \
|
||||
__func__, __LINE__)
|
||||
#define NF10BMAC_READ_4_BE(sc, reg) \
|
||||
nf10bmac_read_4_be((sc)->nf10bmac_rx_mem_res, (reg), \
|
||||
__func__, __LINE__)
|
||||
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
static void nf10bmac_tick(void *);
|
||||
#endif
|
||||
static int nf10bmac_detach(device_t);
|
||||
|
||||
devclass_t nf10bmac_devclass;
|
||||
|
||||
|
||||
static int
|
||||
nf10bmac_tx_locked(struct nf10bmac_softc *sc, struct mbuf *m)
|
||||
{
|
||||
int32_t len, l, ml;
|
||||
uint32_t m4, val4;
|
||||
|
||||
NF10BMAC_LOCK_ASSERT(sc);
|
||||
|
||||
KASSERT(m != NULL, ("%s: m is null: sc=%p", __func__, sc));
|
||||
KASSERT(m->m_flags & M_PKTHDR, ("%s: not a pkthdr: m=%p", __func__, m));
|
||||
/*
|
||||
* Copy to buffer to minimize our pain as we can only store
|
||||
* double words which, after the first mbuf gets out of alignment
|
||||
* quite quickly.
|
||||
*/
|
||||
m_copydata(m, 0, m->m_pkthdr.len, sc->nf10bmac_tx_buf);
|
||||
len = m->m_pkthdr.len;
|
||||
|
||||
/* Write the length at start of packet. */
|
||||
NF10BMAC_WRITE_4(sc, NF10BMAC_TX_LEN, len);
|
||||
|
||||
/* Write the meta data and data. */
|
||||
ml = len / sizeof(val4);
|
||||
len -= (ml * sizeof(val4));
|
||||
for (l = 0; l <= ml; l++) {
|
||||
int32_t cl;
|
||||
|
||||
cl = sizeof(val4);
|
||||
m4 = (NF10BMAC_TUSER_CPU0 << NF10BMAC_DATA_SPORT_SHIFT);
|
||||
if (l == ml || (len == 0 && l == (ml - 1))) {
|
||||
if (l == ml && len == 0) {
|
||||
break;
|
||||
} else {
|
||||
uint8_t s;
|
||||
int sl;
|
||||
|
||||
if (l == (ml - 1))
|
||||
len = 4;
|
||||
cl = len;
|
||||
|
||||
for (s = 0, sl = len; sl > 0; sl--)
|
||||
s |= (1 << (sl - 1));
|
||||
m4 |= (s & NF10BMAC_DATA_STRB);
|
||||
m4 |= NF10BMAC_DATA_LAST;
|
||||
}
|
||||
} else {
|
||||
m4 |= NF10BMAC_DATA_STRB;
|
||||
}
|
||||
NF10BMAC_WRITE_4(sc, NF10BMAC_TX_META, m4);
|
||||
bcopy(&sc->nf10bmac_tx_buf[l*sizeof(val4)], &val4, cl);
|
||||
NF10BMAC_WRITE_4_BE(sc, NF10BMAC_TX_DATA, val4);
|
||||
}
|
||||
|
||||
/* If anyone is interested give them a copy. */
|
||||
BPF_MTAP(sc->nf10bmac_ifp, m);
|
||||
|
||||
m_freem(m);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
nf10bmac_start_locked(struct ifnet *ifp)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
int count, error;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
NF10BMAC_LOCK_ASSERT(sc);
|
||||
|
||||
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
||||
IFF_DRV_RUNNING || (sc->nf10bmac_flags & NF10BMAC_FLAGS_LINK) == 0)
|
||||
return;
|
||||
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
/*
|
||||
* Disable the watchdog while sending, we are batching packets.
|
||||
* Though we should never reach 5 seconds, and are holding the lock,
|
||||
* but who knows.
|
||||
*/
|
||||
sc->nf10bmac_watchdog_timer = 0;
|
||||
#endif
|
||||
|
||||
/* Send up to MAX_PKTS_PER_TX_LOOP packets. */
|
||||
for (count = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
|
||||
count < NF10BMAC_MAX_PKTS; count++) {
|
||||
struct mbuf *m;
|
||||
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL)
|
||||
break;
|
||||
error = nf10bmac_tx_locked(sc, m);
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
done:
|
||||
/* If the IP core walks into Nekromanteion try to bail out. */
|
||||
/* XXX-BZ useless until we have direct FIFO fill status feedback. */
|
||||
if (count > 0)
|
||||
sc->nf10bmac_watchdog_timer = NF10BMAC_WATCHDOG_TIME;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
nf10bmac_start(struct ifnet *ifp)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
NF10BMAC_LOCK(sc);
|
||||
nf10bmac_start_locked(ifp);
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
nf10bmac_eat_packet_munch_munch(struct nf10bmac_softc *sc)
|
||||
{
|
||||
uint32_t m4, val4;
|
||||
|
||||
do {
|
||||
m4 = NF10BMAC_READ_4_BE(sc, NF10BMAC_RX_META);
|
||||
if ((m4 & NF10BMAC_DATA_STRB) != 0)
|
||||
val4 = NF10BMAC_READ_4_BE(sc, NF10BMAC_RX_DATA);
|
||||
} while ((m4 & NF10BMAC_DATA_STRB) != 0 &&
|
||||
(m4 & NF10BMAC_DATA_LAST) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
nf10bmac_rx_locked(struct nf10bmac_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
uint32_t m4, val4;
|
||||
int32_t len, l;
|
||||
|
||||
/*
|
||||
* General problem here in case we need to sync ourselves to the
|
||||
* beginning of a packet. Length will only be set for the first
|
||||
* read, and together with strb we can detect the begining (or
|
||||
* skip to tlast).
|
||||
*/
|
||||
|
||||
len = NF10BMAC_READ_4(sc, NF10BMAC_RX_LEN);
|
||||
if (len > (MCLBYTES - ETHER_ALIGN)) {
|
||||
nf10bmac_eat_packet_munch_munch(sc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
m4 = NF10BMAC_READ_4(sc, NF10BMAC_RX_META);
|
||||
if (len == 0 && (m4 & NF10BMAC_DATA_STRB) == 0) {
|
||||
/* No packet data available. */
|
||||
return (0);
|
||||
} else if (len == 0 && (m4 & NF10BMAC_DATA_STRB) != 0) {
|
||||
/* We are in the middle of a packet. */
|
||||
nf10bmac_eat_packet_munch_munch(sc);
|
||||
return (0);
|
||||
} else if ((m4 & NF10BMAC_DATA_STRB) == 0) {
|
||||
/* Invalid length "hint". */
|
||||
device_printf(sc->nf10bmac_dev,
|
||||
"Unexpected length %d on zero strb\n", len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Assume at this point that we have data and a full packet. */
|
||||
if ((len + ETHER_ALIGN) >= MINCLSIZE) {
|
||||
/* Get a cluster. */
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
} else {
|
||||
/* Hey this still fits into the mbuf+pkthdr. */
|
||||
m = m_gethdr(M_NOWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
m->m_len = m->m_pkthdr.len = MHLEN;
|
||||
}
|
||||
/* Make sure upper layers will be aligned. */
|
||||
m_adj(m, ETHER_ALIGN);
|
||||
|
||||
ifp = sc->nf10bmac_ifp;
|
||||
l = 0;
|
||||
/*
|
||||
while ((m4 & NF10BMAC_DATA_STRB) != 0 && l < len) {
|
||||
*/
|
||||
while (l < len) {
|
||||
size_t cl;
|
||||
|
||||
if ((m4 & NF10BMAC_DATA_LAST) == 0 &&
|
||||
(len - l) < sizeof(val4)) {
|
||||
/*
|
||||
* Our length and LAST disagree. We have a valid STRB.
|
||||
* We could continue until we fill the mbuf and just
|
||||
* log the invlid length "hint". For now drop the
|
||||
* packet on the floor and count the error.
|
||||
*/
|
||||
nf10bmac_eat_packet_munch_munch(sc);
|
||||
ifp->if_ierrors++;
|
||||
m_freem(m);
|
||||
return (0);
|
||||
} else if ((len - l) <= sizeof(val4)) {
|
||||
cl = len - l;
|
||||
} else {
|
||||
cl = sizeof(val4);
|
||||
}
|
||||
|
||||
/* Read the first bytes of data as well. */
|
||||
val4 = NF10BMAC_READ_4_BE(sc, NF10BMAC_RX_DATA);
|
||||
bcopy(&val4, (uint8_t *)(m->m_data + l), cl);
|
||||
l += cl;
|
||||
|
||||
if ((m4 & NF10BMAC_DATA_LAST) != 0 || l >= len)
|
||||
break;
|
||||
else {
|
||||
DELAY(50);
|
||||
m4 = NF10BMAC_READ_4(sc, NF10BMAC_RX_META);
|
||||
}
|
||||
|
||||
cl = 10;
|
||||
while ((m4 & NF10BMAC_DATA_STRB) == 0 && cl-- > 0) {
|
||||
DELAY(10);
|
||||
m4 = NF10BMAC_READ_4(sc, NF10BMAC_RX_META);
|
||||
}
|
||||
}
|
||||
/* We should get out of this loop with tlast and tsrb. */
|
||||
if ((m4 & NF10BMAC_DATA_LAST) == 0 || (m4 & NF10BMAC_DATA_STRB) == 0) {
|
||||
device_printf(sc->nf10bmac_dev, "Unexpected rx loop end state: "
|
||||
"m4=0x%08x len=%d l=%d\n", m4, len, l);
|
||||
ifp->if_ierrors++;
|
||||
m_freem(m);
|
||||
return (0);
|
||||
}
|
||||
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
ifp->if_ipackets++;
|
||||
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
(*ifp->if_input)(ifp, m);
|
||||
NF10BMAC_LOCK(sc);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nf10bmac_stop_locked(struct nf10bmac_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
NF10BMAC_LOCK_ASSERT(sc);
|
||||
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
sc->nf10bmac_watchdog_timer = 0;
|
||||
callout_stop(&sc->nf10bmac_tick);
|
||||
#endif
|
||||
|
||||
ifp = sc->nf10bmac_ifp;
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
|
||||
sc->nf10bmac_flags &= ~NF10BMAC_FLAGS_LINK;
|
||||
if_link_state_change(ifp, LINK_STATE_DOWN);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
nf10bmac_reset(struct nf10bmac_softc *sc)
|
||||
{
|
||||
|
||||
/* Currently we cannot do anything. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
nf10bmac_init_locked(struct nf10bmac_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
uint8_t *eaddr;
|
||||
|
||||
NF10BMAC_LOCK_ASSERT(sc);
|
||||
ifp = sc->nf10bmac_ifp;
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Must update the ether address if changed. Given we do not handle
|
||||
* in nf10bmac_ioctl() but it's in the general framework, just always
|
||||
* do it here before nf10bmac_reset().
|
||||
*/
|
||||
eaddr = IF_LLADDR(sc->nf10bmac_ifp);
|
||||
bcopy(eaddr, &sc->nf10bmac_eth_addr, ETHER_ADDR_LEN);
|
||||
/* XXX-BZ we do not have any way to tell the NIC our ether address. */
|
||||
|
||||
/* Make things frind to halt, cleanup, ... */
|
||||
nf10bmac_stop_locked(sc);
|
||||
/* ... reset, ... */
|
||||
nf10bmac_reset(sc);
|
||||
|
||||
/* Memory rings? DMA engine? MC filter? MII? */
|
||||
/* Instead drain the FIFO; or at least a possible first packet.. */
|
||||
nf10bmac_eat_packet_munch_munch(sc);
|
||||
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
|
||||
/* We have no underlying media, fake link state. */
|
||||
sc->nf10bmac_flags = NF10BMAC_FLAGS_LINK; /* Always up. */
|
||||
if_link_state_change(sc->nf10bmac_ifp, LINK_STATE_UP);
|
||||
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
callout_reset(&sc->nf10bmac_tick, hz, nf10bmac_tick, sc);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
nf10bmac_init(void *xsc)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
|
||||
sc = (struct nf10bmac_softc *)xsc;
|
||||
NF10BMAC_LOCK(sc);
|
||||
nf10bmac_init_locked(sc);
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
static void
|
||||
nf10bmac_watchdog(struct nf10bmac_softc *sc)
|
||||
{
|
||||
|
||||
NF10BMAC_LOCK_ASSERT(sc);
|
||||
|
||||
if (sc->nf10bmac_watchdog_timer == 0 || --sc->nf10bmac_watchdog_timer > 0)
|
||||
return;
|
||||
|
||||
device_printf(sc->nf10bmac_dev, "watchdog timeout\n");
|
||||
sc->nf10bmac_ifp->if_oerrors++;
|
||||
|
||||
sc->nf10bmac_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
nf10bmac_init_locked(sc);
|
||||
|
||||
if (!IFQ_DRV_IS_EMPTY(&sc->nf10bmac_ifp->if_snd))
|
||||
nf10bmac_start_locked(sc->nf10bmac_ifp);
|
||||
}
|
||||
|
||||
static void
|
||||
nf10bmac_tick(void *xsc)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = (struct nf10bmac_softc *)xsc;
|
||||
NF10BMAC_LOCK_ASSERT(sc);
|
||||
ifp = sc->nf10bmac_ifp;
|
||||
|
||||
nf10bmac_watchdog(sc);
|
||||
callout_reset(&sc->nf10bmac_tick, hz, nf10bmac_tick, sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static int
|
||||
nf10bmac_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
int rx_npkts = 0;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
NF10BMAC_LOCK(sc);
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
return (rx_npkts);
|
||||
}
|
||||
|
||||
while (rx_npkts < count) {
|
||||
int c;
|
||||
|
||||
c = nf10bmac_rx_locked(sc);
|
||||
rx_npkts += c;
|
||||
if (c == 0)
|
||||
break;
|
||||
}
|
||||
nf10bmac_start_locked(ifp);
|
||||
|
||||
if (rx_npkts > 0 || cmd == POLL_AND_CHECK_STATUS) {
|
||||
/* We currently cannot do much. */
|
||||
;
|
||||
}
|
||||
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
return (rx_npkts);
|
||||
}
|
||||
#else
|
||||
#error We only support polling mode
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
static int
|
||||
nf10bmac_media_change(struct ifnet *ifp __unused)
|
||||
{
|
||||
|
||||
/* Do nothing. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
nf10bmac_media_status(struct ifnet *ifp __unused, struct ifmediareq *imr)
|
||||
{
|
||||
|
||||
imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
|
||||
imr->ifm_active = IFM_ETHER | IFM_10G_T | IFM_FDX;
|
||||
}
|
||||
|
||||
static int
|
||||
nf10bmac_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
struct ifreq *ifr;
|
||||
int error, mask;
|
||||
|
||||
error = 0;
|
||||
sc = ifp->if_softc;
|
||||
ifr = (struct ifreq *)data;
|
||||
|
||||
switch (command) {
|
||||
case SIOCSIFFLAGS:
|
||||
NF10BMAC_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
|
||||
((ifp->if_flags ^ sc->nf10bmac_if_flags) &
|
||||
(IFF_PROMISC | IFF_ALLMULTI)) != 0)
|
||||
/* Nothing we can do. */ ;
|
||||
else
|
||||
nf10bmac_init_locked(sc);
|
||||
} else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
nf10bmac_stop_locked(sc);
|
||||
sc->nf10bmac_if_flags = ifp->if_flags;
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
break;
|
||||
case SIOCSIFCAP:
|
||||
NF10BMAC_LOCK(sc);
|
||||
mask = ifr->ifr_reqcap ^ ifp->if_capenable;
|
||||
#ifdef DEVICE_POLLING
|
||||
if ((mask & IFCAP_POLLING) != 0 &&
|
||||
(IFCAP_POLLING & ifp->if_capabilities) != 0) {
|
||||
ifp->if_capenable ^= IFCAP_POLLING;
|
||||
if ((IFCAP_POLLING & ifp->if_capenable) != 0) {
|
||||
|
||||
error = ether_poll_register(nf10bmac_poll, ifp);
|
||||
if (error != 0) {
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not allow disabling of polling if we do
|
||||
* not have interrupts.
|
||||
*/
|
||||
} else {
|
||||
ifp->if_capenable ^= IFCAP_POLLING;
|
||||
error = EINVAL;
|
||||
}
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
break;
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCSIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->nf10bmac_media, command);
|
||||
break;
|
||||
default:
|
||||
error = ether_ioctl(ifp, command, data);
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generic device handling routines.
|
||||
*/
|
||||
int
|
||||
nf10bmac_attach(device_t dev)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
mtx_init(&sc->nf10bmac_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF);
|
||||
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
callout_init_mtx(&sc->nf10bmac_tick, &sc->nf10bmac_mtx, 0);
|
||||
#endif
|
||||
|
||||
sc->nf10bmac_tx_buf = malloc(ETHER_MAX_LEN_JUMBO, M_DEVBUF, M_WAITOK);
|
||||
|
||||
/* Reset the adapter. */
|
||||
nf10bmac_reset(sc);
|
||||
|
||||
/* Setup interface. */
|
||||
ifp = sc->nf10bmac_ifp = if_alloc(IFT_ETHER);
|
||||
if (ifp == NULL) {
|
||||
device_printf(dev, "if_alloc() failed\n");
|
||||
error = ENOSPC;
|
||||
goto err;
|
||||
}
|
||||
ifp->if_softc = sc;
|
||||
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; /* | IFF_MULTICAST; */
|
||||
ifp->if_ioctl = nf10bmac_ioctl;
|
||||
ifp->if_start = nf10bmac_start;
|
||||
ifp->if_init = nf10bmac_init;
|
||||
IFQ_SET_MAXLEN(&ifp->if_snd, NF10BMAC_MAX_PKTS - 1);
|
||||
ifp->if_snd.ifq_drv_maxlen = NF10BMAC_MAX_PKTS - 1;
|
||||
IFQ_SET_READY(&ifp->if_snd);
|
||||
|
||||
/* Call media-indepedent attach routine. */
|
||||
ether_ifattach(ifp, sc->nf10bmac_eth_addr);
|
||||
|
||||
/* Tell the upper layer(s) about vlan mtu support. */
|
||||
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
|
||||
ifp->if_capabilities |= IFCAP_VLAN_MTU;
|
||||
ifp->if_capenable = ifp->if_capabilities;
|
||||
#ifdef DEVICE_POLLING
|
||||
/* We will enable polling by default if no irqs available. See below. */
|
||||
ifp->if_capabilities |= IFCAP_POLLING;
|
||||
#endif
|
||||
|
||||
/* We need more media attention. Fake it! */
|
||||
ifmedia_init(&sc->nf10bmac_media, 0, nf10bmac_media_change,
|
||||
nf10bmac_media_status);
|
||||
ifmedia_add(&sc->nf10bmac_media, IFM_ETHER | IFM_10G_T, 0, NULL);
|
||||
ifmedia_set(&sc->nf10bmac_media, IFM_ETHER | IFM_10G_T);
|
||||
|
||||
/* Interrupts would go here. */
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
ifp->if_capenable |= IFCAP_POLLING;
|
||||
device_printf(dev, "forcing to polling due to no interrupts\n");
|
||||
error = ether_poll_register(nf10bmac_poll, ifp);
|
||||
if (error != 0)
|
||||
goto err;
|
||||
#else
|
||||
device_printf(dev, "no DEVICE_POLLING in kernel and no IRQs\n");
|
||||
error = ENXIO;
|
||||
#endif
|
||||
|
||||
err:
|
||||
if (error != 0)
|
||||
nf10bmac_detach(dev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nf10bmac_detach(device_t dev)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
KASSERT(mtx_initialized(&sc->nf10bmac_mtx),
|
||||
("%s: mutex not initialized", device_get_nameunit(dev)));
|
||||
ifp = sc->nf10bmac_ifp;
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
if (ifp->if_capenable & IFCAP_POLLING)
|
||||
ether_poll_deregister(ifp);
|
||||
#endif
|
||||
|
||||
/* Only cleanup if attach succeeded. */
|
||||
if (device_is_attached(dev)) {
|
||||
NF10BMAC_LOCK(sc);
|
||||
nf10bmac_stop_locked(sc);
|
||||
NF10BMAC_UNLOCK(sc);
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
callout_drain(&sc->nf10bmac_tick);
|
||||
#endif
|
||||
ether_ifdetach(ifp);
|
||||
}
|
||||
|
||||
if (ifp != NULL)
|
||||
if_free(ifp);
|
||||
ifmedia_removeall(&sc->nf10bmac_media);
|
||||
|
||||
mtx_destroy(&sc->nf10bmac_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Shared with the attachment specific (e.g., fdt) implementation. */
|
||||
void
|
||||
nf10bmac_detach_resources(device_t dev)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if (sc->nf10bmac_mem_res != NULL) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
sc->nf10bmac_mem_rid, sc->nf10bmac_mem_res);
|
||||
sc->nf10bmac_mem_res = NULL;
|
||||
}
|
||||
if (sc->nf10bmac_rx_mem_res != NULL) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
sc->nf10bmac_rx_mem_rid, sc->nf10bmac_rx_mem_res);
|
||||
sc->nf10bmac_rx_mem_res = NULL;
|
||||
}
|
||||
if (sc->nf10bmac_tx_mem_res != NULL) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
sc->nf10bmac_tx_mem_rid, sc->nf10bmac_tx_mem_res);
|
||||
sc->nf10bmac_tx_mem_res = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
nf10bmac_detach_dev(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = nf10bmac_detach(dev);
|
||||
if (error) {
|
||||
/* We are basically in undefined state now. */
|
||||
device_printf(dev, "nf10bmac_detach() failed: %d\n", error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
nf10bmac_detach_resources(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* end */
|
179
sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c
Normal file
179
sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*-
|
||||
* Copyright (c) 2013-2014 Bjoern A. Zeeb
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
* Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||
* ("MRC2"), as part of the DARPA MRC research programme.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This driver is modelled after atse(4). We need to seriously reduce the
|
||||
* per-driver code we have to write^wcopy & paste.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_var.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include "if_nf10bmacreg.h"
|
||||
|
||||
static int
|
||||
nf10bmac_probe_fdt(device_t dev)
|
||||
{
|
||||
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (ofw_bus_is_compatible(dev, "netfpag10g,nf10bmac")) {
|
||||
device_set_desc(dev, "NetFPGA-10G Embedded CPU Ethernet Core");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
nf10bmac_attach_fdt(device_t dev)
|
||||
{
|
||||
struct nf10bmac_softc *sc;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->nf10bmac_dev = dev;
|
||||
sc->nf10bmac_unit = device_get_unit(dev);
|
||||
|
||||
/*
|
||||
* FDT lists our resources. For convenience we use three different
|
||||
* mappings. We need to attach them in the oder specified in .dts:
|
||||
* TX (size 0xc), RX (size 0xc), LOOP (size 0x4).
|
||||
*/
|
||||
|
||||
/*
|
||||
* TX and TX metadata FIFO memory region.
|
||||
* 0x00: 32bit FIFO data,
|
||||
* 0x04: 32bit FIFO metadata,
|
||||
* 0x08: 32bit packet length.
|
||||
*/
|
||||
sc->nf10bmac_tx_mem_rid = 0;
|
||||
sc->nf10bmac_tx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->nf10bmac_tx_mem_rid, RF_ACTIVE);
|
||||
if (sc->nf10bmac_tx_mem_res == NULL) {
|
||||
device_printf(dev, "failed to map memory for TX FIFO\n");
|
||||
error = ENXIO;
|
||||
goto err;
|
||||
}
|
||||
if (bootverbose)
|
||||
device_printf(sc->nf10bmac_dev, "TX FIFO at mem %p-%p\n",
|
||||
(void *)rman_get_start(sc->nf10bmac_tx_mem_res),
|
||||
(void *)(rman_get_start(sc->nf10bmac_tx_mem_res) +
|
||||
rman_get_size(sc->nf10bmac_tx_mem_res)));
|
||||
|
||||
/*
|
||||
* RX and RXC metadata FIFO memory region.
|
||||
* 0x00: 32bit FIFO data,
|
||||
* 0x04: 32bit FIFO metadata,
|
||||
* 0x08: 32bit packet length.
|
||||
*/
|
||||
sc->nf10bmac_rx_mem_rid = 1;
|
||||
sc->nf10bmac_rx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->nf10bmac_rx_mem_rid, RF_ACTIVE);
|
||||
if (sc->nf10bmac_rx_mem_res == NULL) {
|
||||
device_printf(dev, "failed to map memory for RX FIFO\n");
|
||||
error = ENXIO;
|
||||
goto err;
|
||||
}
|
||||
if (bootverbose)
|
||||
device_printf(sc->nf10bmac_dev, "RX FIFO at mem %p-%p\n",
|
||||
(void *)rman_get_start(sc->nf10bmac_rx_mem_res),
|
||||
(void *)(rman_get_start(sc->nf10bmac_rx_mem_res) +
|
||||
rman_get_size(sc->nf10bmac_rx_mem_res)));
|
||||
|
||||
/*
|
||||
* LOOP memory region (this could be a general control region).
|
||||
* 0x00: 32bit register to enable a Y-"lopback".
|
||||
*/
|
||||
sc->nf10bmac_mem_rid = 2;
|
||||
sc->nf10bmac_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->nf10bmac_mem_rid, RF_ACTIVE);
|
||||
if (sc->nf10bmac_mem_res == NULL) {
|
||||
device_printf(dev, "failed to map memory for CTRL region\n");
|
||||
error = ENXIO;
|
||||
goto err;
|
||||
}
|
||||
if (bootverbose)
|
||||
device_printf(sc->nf10bmac_dev, "CTRL region at mem %p-%p\n",
|
||||
(void *)rman_get_start(sc->nf10bmac_mem_res),
|
||||
(void *)(rman_get_start(sc->nf10bmac_mem_res) +
|
||||
rman_get_size(sc->nf10bmac_mem_res)));
|
||||
|
||||
error = nf10bmac_attach(dev);
|
||||
if (error)
|
||||
goto err;
|
||||
|
||||
return (0);
|
||||
|
||||
err:
|
||||
/* Cleanup. */
|
||||
nf10bmac_detach_resources(dev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static device_method_t nf10bmac_methods_fdt[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, nf10bmac_probe_fdt),
|
||||
DEVMETHOD(device_attach, nf10bmac_attach_fdt),
|
||||
DEVMETHOD(device_detach, nf10bmac_detach_dev),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t nf10bmac_driver_fdt = {
|
||||
"nf10bmac",
|
||||
nf10bmac_methods_fdt,
|
||||
sizeof(struct nf10bmac_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(nf10bmac, simplebus, nf10bmac_driver_fdt, nf10bmac_devclass, 0,0);
|
||||
|
||||
/* end */
|
67
sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h
Normal file
67
sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Bjoern A. Zeeb
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
* Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
|
||||
* ("MRC2"), as part of the DARPA MRC research programme.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _DEV_IF_NF10BMACREG_H
|
||||
#define _DEV_IF_NF10BMACREG_H
|
||||
|
||||
struct nf10bmac_softc {
|
||||
struct ifnet *nf10bmac_ifp;
|
||||
struct resource *nf10bmac_tx_mem_res;
|
||||
struct resource *nf10bmac_rx_mem_res;
|
||||
struct resource *nf10bmac_mem_res;
|
||||
uint8_t *nf10bmac_tx_buf;
|
||||
device_t nf10bmac_dev;
|
||||
int nf10bmac_unit;
|
||||
int nf10bmac_tx_mem_rid;
|
||||
int nf10bmac_rx_mem_rid;
|
||||
int nf10bmac_mem_rid;
|
||||
int nf10bmac_if_flags;
|
||||
uint32_t nf10bmac_flags;
|
||||
#define NF10BMAC_FLAGS_LINK 0x00000001
|
||||
uint8_t nf10bmac_eth_addr[ETHER_ADDR_LEN];
|
||||
#ifdef ENABLE_WATCHDOG
|
||||
uint16_t nf10bmac_watchdog_timer;
|
||||
struct callout nf10bmac_tick;
|
||||
#endif
|
||||
struct ifmedia nf10bmac_media; /* to fake it. */
|
||||
struct mtx nf10bmac_mtx;
|
||||
};
|
||||
|
||||
int nf10bmac_attach(device_t);
|
||||
int nf10bmac_detach_dev(device_t);
|
||||
void nf10bmac_detach_resources(device_t);
|
||||
|
||||
extern devclass_t nf10bmac_devclass;
|
||||
|
||||
#endif /* _DEV_IF_NF10BMACREG_H */
|
||||
|
||||
/* end */
|
@ -6,6 +6,8 @@ dev/altera/jtag_uart/altera_jtag_uart_cons.c optional altera_jtag_uart
|
||||
dev/altera/jtag_uart/altera_jtag_uart_tty.c optional altera_jtag_uart
|
||||
dev/altera/jtag_uart/altera_jtag_uart_fdt.c optional altera_jtag_uart fdt
|
||||
dev/altera/jtag_uart/altera_jtag_uart_nexus.c optional altera_jtag_uart
|
||||
dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c optional netfpga10g_nf10bmac fdt
|
||||
dev/netfpga10g/nf10bmac/if_nf10bmac.c optional netfpga10g_nf10bmac
|
||||
dev/terasic/de4led/terasic_de4led.c optional terasic_de4led
|
||||
dev/terasic/de4led/terasic_de4led_fdt.c optional terasic_de4led fdt
|
||||
dev/terasic/de4led/terasic_de4led_nexus.c optional terasic_de4led
|
||||
|
@ -19,6 +19,11 @@ makeoptions FDT_DTS_FILE=beri-netfpga.dts
|
||||
#device uart
|
||||
device altera_jtag_uart
|
||||
|
||||
device bpf
|
||||
|
||||
options DEVICE_POLLING
|
||||
device netfpga10g_nf10bmac
|
||||
|
||||
#
|
||||
# This kernel configuration uses an embedded memory root file system.
|
||||
# Adjust the following path and size based on local requirements.
|
||||
|
@ -234,6 +234,7 @@ SUBDIR= \
|
||||
${_ncp} \
|
||||
${_ncv} \
|
||||
${_ndis} \
|
||||
netfpga10g \
|
||||
${_netgraph} \
|
||||
${_nfe} \
|
||||
nfs_common \
|
||||
|
12
sys/modules/netfpga10g/Makefile
Normal file
12
sys/modules/netfpga10g/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
SUBDIR=
|
||||
SUBDIR+= ${_nf10bmac}
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "mips"
|
||||
_nf10bmac= nf10bmac
|
||||
.endif
|
||||
|
||||
.include <bsd.subdir.mk>
|
16
sys/modules/netfpga10g/nf10bmac/Makefile
Normal file
16
sys/modules/netfpga10g/nf10bmac/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../dev/netfpga10g/nf10bmac
|
||||
|
||||
KMOD= if_nf10bmac
|
||||
SRCS= if_nf10bmac.c
|
||||
SRCS+= device_if.h bus_if.h pci_if.h
|
||||
SRCS+= opt_device_polling.h
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "mips"
|
||||
SRCS+= if_nf10bmac_fdt.c ofw_bus_if.h
|
||||
.endif
|
||||
|
||||
CFLAGS+= -DDEVICE_POLLING
|
||||
|
||||
.include <bsd.kmod.mk>
|
Loading…
Reference in New Issue
Block a user