Deleted Added
full compact
if_arge.c (289476) if_arge.c (289671)
1/*-
2 * Copyright (c) 2009, Oleksandr Tymoshenko
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2009, Oleksandr Tymoshenko
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/mips/atheros/if_arge.c 289476 2015-10-18 00:59:28Z adrian $");
29__FBSDID("$FreeBSD: head/sys/mips/atheros/if_arge.c 289671 2015-10-21 01:41:18Z adrian $");
30
31/*
32 * AR71XX gigabit ethernet driver
33 */
34#ifdef HAVE_KERNEL_OPTION_HEADERS
35#include "opt_device_polling.h"
36#endif
37

--- 2122 unchanged lines hidden (view full) ---

2160{
2161 struct arge_desc *desc;
2162 struct arge_rxdesc *rxd;
2163 struct mbuf *m;
2164 bus_dma_segment_t segs[1];
2165 bus_dmamap_t map;
2166 int nsegs;
2167
30
31/*
32 * AR71XX gigabit ethernet driver
33 */
34#ifdef HAVE_KERNEL_OPTION_HEADERS
35#include "opt_device_polling.h"
36#endif
37

--- 2122 unchanged lines hidden (view full) ---

2160{
2161 struct arge_desc *desc;
2162 struct arge_rxdesc *rxd;
2163 struct mbuf *m;
2164 bus_dma_segment_t segs[1];
2165 bus_dmamap_t map;
2166 int nsegs;
2167
2168 /* XXX TODO: should just allocate an explicit 2KiB buffer */
2168 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
2169 if (m == NULL)
2170 return (ENOBUFS);
2171 m->m_len = m->m_pkthdr.len = MCLBYTES;
2172
2173 /*
2174 * Add extra space to "adjust" (copy) the packet back to be aligned
2175 * for purposes of IPv4/IPv6 header contents.
2176 */
2169 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
2170 if (m == NULL)
2171 return (ENOBUFS);
2172 m->m_len = m->m_pkthdr.len = MCLBYTES;
2173
2174 /*
2175 * Add extra space to "adjust" (copy) the packet back to be aligned
2176 * for purposes of IPv4/IPv6 header contents.
2177 */
2177 m_adj(m, sizeof(uint64_t));
2178 if (sc->arge_hw_flags & ARGE_HW_FLG_RX_DESC_ALIGN_4BYTE)
2179 m_adj(m, sizeof(uint64_t));
2180 /*
2181 * If it's a 1-byte aligned buffer, then just offset it two bytes
2182 * and that will give us a hopefully correctly DWORD aligned
2183 * L3 payload - and we won't have to undo it afterwards.
2184 */
2185 else if (sc->arge_hw_flags & ARGE_HW_FLG_RX_DESC_ALIGN_1BYTE)
2186 m_adj(m, sizeof(uint16_t));
2178
2179 if (bus_dmamap_load_mbuf_sg(sc->arge_cdata.arge_rx_tag,
2180 sc->arge_cdata.arge_rx_sparemap, m, segs, &nsegs, 0) != 0) {
2181 m_freem(m);
2182 return (ENOBUFS);
2183 }
2184 KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
2185
2186 rxd = &sc->arge_cdata.arge_rxdesc[idx];
2187 if (rxd->rx_m != NULL) {
2188 bus_dmamap_unload(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap);
2187
2188 if (bus_dmamap_load_mbuf_sg(sc->arge_cdata.arge_rx_tag,
2189 sc->arge_cdata.arge_rx_sparemap, m, segs, &nsegs, 0) != 0) {
2190 m_freem(m);
2191 return (ENOBUFS);
2192 }
2193 KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
2194
2195 rxd = &sc->arge_cdata.arge_rxdesc[idx];
2196 if (rxd->rx_m != NULL) {
2197 bus_dmamap_unload(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap);
2198 /* XXX TODO: free rx_m? */
2199 device_printf(sc->arge_dev,
2200 "%s: ring[%d] rx_m wasn't free?\n",
2201 __func__,
2202 idx);
2189 }
2190 map = rxd->rx_dmamap;
2191 rxd->rx_dmamap = sc->arge_cdata.arge_rx_sparemap;
2192 sc->arge_cdata.arge_rx_sparemap = map;
2193 rxd->rx_m = m;
2194 desc = rxd->desc;
2195 if ((sc->arge_hw_flags & ARGE_HW_FLG_RX_DESC_ALIGN_4BYTE) &&
2196 segs[0].ds_addr & 3)
2197 panic("RX packet address unaligned");
2198 desc->packet_addr = segs[0].ds_addr;
2199 desc->packet_ctrl = ARGE_DESC_EMPTY | ARGE_DMASIZE(segs[0].ds_len);
2200
2201 bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag,
2202 sc->arge_cdata.arge_rx_ring_map,
2203 BUS_DMASYNC_PREWRITE);
2204
2205 return (0);
2206}
2207
2203 }
2204 map = rxd->rx_dmamap;
2205 rxd->rx_dmamap = sc->arge_cdata.arge_rx_sparemap;
2206 sc->arge_cdata.arge_rx_sparemap = map;
2207 rxd->rx_m = m;
2208 desc = rxd->desc;
2209 if ((sc->arge_hw_flags & ARGE_HW_FLG_RX_DESC_ALIGN_4BYTE) &&
2210 segs[0].ds_addr & 3)
2211 panic("RX packet address unaligned");
2212 desc->packet_addr = segs[0].ds_addr;
2213 desc->packet_ctrl = ARGE_DESC_EMPTY | ARGE_DMASIZE(segs[0].ds_len);
2214
2215 bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag,
2216 sc->arge_cdata.arge_rx_ring_map,
2217 BUS_DMASYNC_PREWRITE);
2218
2219 return (0);
2220}
2221
2222/*
2223 * Move the data backwards 16 bits to (hopefully!) ensure the
2224 * IPv4/IPv6 payload is aligned.
2225 *
2226 * This is required for earlier hardware where the RX path
2227 * requires DWORD aligned buffers.
2228 */
2208static __inline void
2209arge_fixup_rx(struct mbuf *m)
2210{
2211 int i;
2212 uint16_t *src, *dst;
2213
2214 src = mtod(m, uint16_t *);
2215 dst = src - 1;

--- 123 unchanged lines hidden (view full) ---

2339
2340 prog++;
2341
2342 packet_len = ARGE_DMASIZE(cur_rx->packet_ctrl);
2343 bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap,
2344 BUS_DMASYNC_POSTREAD);
2345 m = rxd->rx_m;
2346
2229static __inline void
2230arge_fixup_rx(struct mbuf *m)
2231{
2232 int i;
2233 uint16_t *src, *dst;
2234
2235 src = mtod(m, uint16_t *);
2236 dst = src - 1;

--- 123 unchanged lines hidden (view full) ---

2360
2361 prog++;
2362
2363 packet_len = ARGE_DMASIZE(cur_rx->packet_ctrl);
2364 bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap,
2365 BUS_DMASYNC_POSTREAD);
2366 m = rxd->rx_m;
2367
2347 arge_fixup_rx(m);
2368 /*
2369 * If the MAC requires 4 byte alignment then the RX setup
2370 * routine will have pre-offset things; so un-offset it here.
2371 */
2372 if (sc->arge_hw_flags & ARGE_HW_FLG_RX_DESC_ALIGN_4BYTE)
2373 arge_fixup_rx(m);
2374
2348 m->m_pkthdr.rcvif = ifp;
2349 /* Skip 4 bytes of CRC */
2350 m->m_pkthdr.len = m->m_len = packet_len - ETHER_CRC_LEN;
2351 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
2352 rx_npkts++;
2353
2354 ARGE_UNLOCK(sc);
2355 (*ifp->if_input)(ifp, m);

--- 246 unchanged lines hidden ---
2375 m->m_pkthdr.rcvif = ifp;
2376 /* Skip 4 bytes of CRC */
2377 m->m_pkthdr.len = m->m_len = packet_len - ETHER_CRC_LEN;
2378 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
2379 rx_npkts++;
2380
2381 ARGE_UNLOCK(sc);
2382 (*ifp->if_input)(ifp, m);

--- 246 unchanged lines hidden ---