1/*-
2 * Copyright (c) 2012-2014 Bjoern A. Zeeb
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
7 * ("MRC2"), as part of the DARPA MRC research programme.
8 *
--- 23 unchanged lines hidden (view full) ---
32 *
33 * TODO:
34 * - figure out on the HW side why some data is LE and some is BE.
35 * - general set of improvements possible (e.g., reduce times of copying,
36 * do on-the-copy checksum calculations)
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: head/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c 267920 2014-06-26 17:10:07Z bz $");
41
42#include "opt_device_polling.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/bus.h>
48#include <sys/endian.h>
--- 63 unchanged lines hidden (view full) ---
112#define NF10BMAC_TUSER_CPU3 (1 << 7)
113
114#define NF10BMAC_DATA_LEN_MASK 0x0000ffff
115#define NF10BMAC_DATA_DPORT_MASK 0xff000000
116#define NF10BMAC_DATA_DPORT_SHIFT 24
117#define NF10BMAC_DATA_SPORT_MASK 0x00ff0000
118#define NF10BMAC_DATA_SPORT_SHIFT 16
119#define NF10BMAC_DATA_LAST 0x00008000
120#ifdef NF10BMAC_64BIT
121#define NF10BMAC_DATA_STRB 0x000000ff
122#define REGWTYPE uint64_t
123#else
124#define NF10BMAC_DATA_STRB 0x0000000f
125#define REGWTYPE uint32_t
126#endif
127
128
129static inline void
130nf10bmac_write(struct resource *res, REGWTYPE reg, REGWTYPE val,
131 const char *f __unused, const int l __unused)
132{
133
134#ifdef NF10BMAC_64BIT
135 bus_write_8(res, reg, htole64(val));
136#else
137 bus_write_4(res, reg, htole32(val));
138#endif
139}
140
141static inline REGWTYPE
142nf10bmac_read(struct resource *res, REGWTYPE reg,
143 const char *f __unused, const int l __unused)
144{
145
146#ifdef NF10BMAC_64BIT
147 return (le64toh(bus_read_8(res, reg)));
148#else
149 return (le32toh(bus_read_4(res, reg)));
150#endif
151}
152
153static inline void
154nf10bmac_write_be(struct resource *res, REGWTYPE reg, REGWTYPE val,
155 const char *f __unused, const int l __unused)
156{
157
158#ifdef NF10BMAC_64BIT
159 bus_write_8(res, reg, htobe64(val));
160#else
161 bus_write_4(res, reg, htobe32(val));
162#endif
163}
164
165
166static inline REGWTYPE
167nf10bmac_read_be(struct resource *res, REGWTYPE reg,
168 const char *f __unused, const int l __unused)
169{
170
171#ifdef NF10BMAC_64BIT
172 return (be64toh(bus_read_8(res, reg)));
173#else
174 return (be32toh(bus_read_4(res, reg)));
175#endif
176}
177
178#define NF10BMAC_WRITE_CTRL(sc, reg, val) \
179 nf10bmac_write((sc)->nf10bmac_ctrl_res, (reg), (val), \
180 __func__, __LINE__)
181#define NF10BMAC_WRITE(sc, reg, val) \
182 nf10bmac_write((sc)->nf10bmac_tx_mem_res, (reg), (val), \
183 __func__, __LINE__)
--- 29 unchanged lines hidden (view full) ---
213
214devclass_t nf10bmac_devclass;
215
216
217static int
218nf10bmac_tx_locked(struct nf10bmac_softc *sc, struct mbuf *m)
219{
220 int32_t len, l, ml;
221 REGWTYPE md, val;
222
223 NF10BMAC_LOCK_ASSERT(sc);
224
225 KASSERT(m != NULL, ("%s: m is null: sc=%p", __func__, sc));
226 KASSERT(m->m_flags & M_PKTHDR, ("%s: not a pkthdr: m=%p", __func__, m));
227 /*
228 * Copy to buffer to minimize our pain as we can only store
229 * double words which, after the first mbuf gets out of alignment
--- 98 unchanged lines hidden (view full) ---
328 NF10BMAC_LOCK(sc);
329 nf10bmac_start_locked(ifp);
330 NF10BMAC_UNLOCK(sc);
331}
332
333static void
334nf10bmac_eat_packet_munch_munch(struct nf10bmac_softc *sc)
335{
336 REGWTYPE md, val;
337
338 do {
339 md = NF10BMAC_READ_BE(sc, NF10BMAC_RX_META);
340 if ((md & NF10BMAC_DATA_STRB) != 0)
341 val = NF10BMAC_READ_BE(sc, NF10BMAC_RX_DATA);
342 } while ((md & NF10BMAC_DATA_STRB) != 0 &&
343 (md & NF10BMAC_DATA_LAST) == 0);
344}
345
346static int
347nf10bmac_rx_locked(struct nf10bmac_softc *sc)
348{
349 struct ifnet *ifp;
350 struct mbuf *m;
351 REGWTYPE md, val;
352 int32_t len, l;
353
354 /*
355 * General problem here in case we need to sync ourselves to the
356 * beginning of a packet. Length will only be set for the first
357 * read, and together with strb we can detect the begining (or
358 * skip to tlast).
359 */
--- 78 unchanged lines hidden (view full) ---
438 while ((md & NF10BMAC_DATA_STRB) == 0 && cl-- > 0) {
439 DELAY(10);
440 md = NF10BMAC_READ(sc, NF10BMAC_RX_META);
441 }
442 }
443 /* We should get out of this loop with tlast and tsrb. */
444 if ((md & NF10BMAC_DATA_LAST) == 0 || (md & NF10BMAC_DATA_STRB) == 0) {
445 device_printf(sc->nf10bmac_dev, "Unexpected rx loop end state: "
446 "md=0x%08jx len=%d l=%d\n", (uintmax_t)md, len, l);
447 ifp->if_ierrors++;
448 m_freem(m);
449 return (0);
450 }
451
452 m->m_pkthdr.len = m->m_len = len;
453 m->m_pkthdr.rcvif = ifp;
454 ifp->if_ipackets++;
--- 515 unchanged lines hidden ---
2 * Copyright (c) 2012-2014 Bjoern A. Zeeb
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
7 * ("MRC2"), as part of the DARPA MRC research programme.
8 *
--- 23 unchanged lines hidden (view full) ---
32 *
33 * TODO:
34 * - figure out on the HW side why some data is LE and some is BE.
35 * - general set of improvements possible (e.g., reduce times of copying,
36 * do on-the-copy checksum calculations)
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: head/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c 267920 2014-06-26 17:10:07Z bz $");
41
42#include "opt_device_polling.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/bus.h>
48#include <sys/endian.h>
--- 63 unchanged lines hidden (view full) ---
112#define NF10BMAC_TUSER_CPU3 (1 << 7)
113
114#define NF10BMAC_DATA_LEN_MASK 0x0000ffff
115#define NF10BMAC_DATA_DPORT_MASK 0xff000000
116#define NF10BMAC_DATA_DPORT_SHIFT 24
117#define NF10BMAC_DATA_SPORT_MASK 0x00ff0000
118#define NF10BMAC_DATA_SPORT_SHIFT 16
119#define NF10BMAC_DATA_LAST 0x00008000
120#ifdef NF10BMAC_64BIT
121#define NF10BMAC_DATA_STRB 0x000000ff
122#define REGWTYPE uint64_t
123#else
124#define NF10BMAC_DATA_STRB 0x0000000f
125#define REGWTYPE uint32_t
126#endif
127
128
129static inline void
130nf10bmac_write(struct resource *res, REGWTYPE reg, REGWTYPE val,
131 const char *f __unused, const int l __unused)
132{
133
134#ifdef NF10BMAC_64BIT
135 bus_write_8(res, reg, htole64(val));
136#else
137 bus_write_4(res, reg, htole32(val));
138#endif
139}
140
141static inline REGWTYPE
142nf10bmac_read(struct resource *res, REGWTYPE reg,
143 const char *f __unused, const int l __unused)
144{
145
146#ifdef NF10BMAC_64BIT
147 return (le64toh(bus_read_8(res, reg)));
148#else
149 return (le32toh(bus_read_4(res, reg)));
150#endif
151}
152
153static inline void
154nf10bmac_write_be(struct resource *res, REGWTYPE reg, REGWTYPE val,
155 const char *f __unused, const int l __unused)
156{
157
158#ifdef NF10BMAC_64BIT
159 bus_write_8(res, reg, htobe64(val));
160#else
161 bus_write_4(res, reg, htobe32(val));
162#endif
163}
164
165
166static inline REGWTYPE
167nf10bmac_read_be(struct resource *res, REGWTYPE reg,
168 const char *f __unused, const int l __unused)
169{
170
171#ifdef NF10BMAC_64BIT
172 return (be64toh(bus_read_8(res, reg)));
173#else
174 return (be32toh(bus_read_4(res, reg)));
175#endif
176}
177
178#define NF10BMAC_WRITE_CTRL(sc, reg, val) \
179 nf10bmac_write((sc)->nf10bmac_ctrl_res, (reg), (val), \
180 __func__, __LINE__)
181#define NF10BMAC_WRITE(sc, reg, val) \
182 nf10bmac_write((sc)->nf10bmac_tx_mem_res, (reg), (val), \
183 __func__, __LINE__)
--- 29 unchanged lines hidden (view full) ---
213
214devclass_t nf10bmac_devclass;
215
216
217static int
218nf10bmac_tx_locked(struct nf10bmac_softc *sc, struct mbuf *m)
219{
220 int32_t len, l, ml;
221 REGWTYPE md, val;
222
223 NF10BMAC_LOCK_ASSERT(sc);
224
225 KASSERT(m != NULL, ("%s: m is null: sc=%p", __func__, sc));
226 KASSERT(m->m_flags & M_PKTHDR, ("%s: not a pkthdr: m=%p", __func__, m));
227 /*
228 * Copy to buffer to minimize our pain as we can only store
229 * double words which, after the first mbuf gets out of alignment
--- 98 unchanged lines hidden (view full) ---
328 NF10BMAC_LOCK(sc);
329 nf10bmac_start_locked(ifp);
330 NF10BMAC_UNLOCK(sc);
331}
332
333static void
334nf10bmac_eat_packet_munch_munch(struct nf10bmac_softc *sc)
335{
336 REGWTYPE md, val;
337
338 do {
339 md = NF10BMAC_READ_BE(sc, NF10BMAC_RX_META);
340 if ((md & NF10BMAC_DATA_STRB) != 0)
341 val = NF10BMAC_READ_BE(sc, NF10BMAC_RX_DATA);
342 } while ((md & NF10BMAC_DATA_STRB) != 0 &&
343 (md & NF10BMAC_DATA_LAST) == 0);
344}
345
346static int
347nf10bmac_rx_locked(struct nf10bmac_softc *sc)
348{
349 struct ifnet *ifp;
350 struct mbuf *m;
351 REGWTYPE md, val;
352 int32_t len, l;
353
354 /*
355 * General problem here in case we need to sync ourselves to the
356 * beginning of a packet. Length will only be set for the first
357 * read, and together with strb we can detect the begining (or
358 * skip to tlast).
359 */
--- 78 unchanged lines hidden (view full) ---
438 while ((md & NF10BMAC_DATA_STRB) == 0 && cl-- > 0) {
439 DELAY(10);
440 md = NF10BMAC_READ(sc, NF10BMAC_RX_META);
441 }
442 }
443 /* We should get out of this loop with tlast and tsrb. */
444 if ((md & NF10BMAC_DATA_LAST) == 0 || (md & NF10BMAC_DATA_STRB) == 0) {
445 device_printf(sc->nf10bmac_dev, "Unexpected rx loop end state: "
446 "md=0x%08jx len=%d l=%d\n", (uintmax_t)md, len, l);
447 ifp->if_ierrors++;
448 m_freem(m);
449 return (0);
450 }
451
452 m->m_pkthdr.len = m->m_len = len;
453 m->m_pkthdr.rcvif = ifp;
454 ifp->if_ipackets++;
--- 515 unchanged lines hidden ---