Tue Oct 13 08:00:15 2015 UTC ()
separate TX dma control data and RX dma control data.

ok by msaitoh@n.o


(knakahara)
diff -r1.353 -r1.354 src/sys/dev/pci/if_wm.c

cvs diff -r1.353 -r1.354 src/sys/dev/pci/if_wm.c (expand / switch to unified diff)

--- src/sys/dev/pci/if_wm.c 2015/10/13 07:53:02 1.353
+++ src/sys/dev/pci/if_wm.c 2015/10/13 08:00:15 1.354
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_wm.c,v 1.353 2015/10/13 07:53:02 knakahara Exp $ */ 1/* $NetBSD: if_wm.c,v 1.354 2015/10/13 08:00:15 knakahara Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. 4 * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -73,27 +73,27 @@ @@ -73,27 +73,27 @@
73 * TODO (in order of importance): 73 * TODO (in order of importance):
74 * 74 *
75 * - Check XXX'ed comments 75 * - Check XXX'ed comments
76 * - EEE (Energy Efficiency Ethernet) 76 * - EEE (Energy Efficiency Ethernet)
77 * - Multi queue 77 * - Multi queue
78 * - Image Unique ID 78 * - Image Unique ID
79 * - LPLU other than PCH* 79 * - LPLU other than PCH*
80 * - Virtual Function 80 * - Virtual Function
81 * - Set LED correctly (based on contents in EEPROM) 81 * - Set LED correctly (based on contents in EEPROM)
82 * - Rework how parameters are loaded from the EEPROM. 82 * - Rework how parameters are loaded from the EEPROM.
83 */ 83 */
84 84
85#include <sys/cdefs.h> 85#include <sys/cdefs.h>
86__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.353 2015/10/13 07:53:02 knakahara Exp $"); 86__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.354 2015/10/13 08:00:15 knakahara Exp $");
87 87
88#ifdef _KERNEL_OPT 88#ifdef _KERNEL_OPT
89#include "opt_net_mpsafe.h" 89#include "opt_net_mpsafe.h"
90#endif 90#endif
91 91
92#include <sys/param.h> 92#include <sys/param.h>
93#include <sys/systm.h> 93#include <sys/systm.h>
94#include <sys/callout.h> 94#include <sys/callout.h>
95#include <sys/mbuf.h> 95#include <sys/mbuf.h>
96#include <sys/malloc.h> 96#include <sys/malloc.h>
97#include <sys/kernel.h> 97#include <sys/kernel.h>
98#include <sys/socket.h> 98#include <sys/socket.h>
99#include <sys/ioctl.h> 99#include <sys/ioctl.h>
@@ -209,55 +209,33 @@ int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX @@ -209,55 +209,33 @@ int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX
209#define WM_MAXTXDMA (2 * round_page(IP_MAXPACKET)) /* for TSO */ 209#define WM_MAXTXDMA (2 * round_page(IP_MAXPACKET)) /* for TSO */
210 210
211/* 211/*
212 * Receive descriptor list size. We have one Rx buffer for normal 212 * Receive descriptor list size. We have one Rx buffer for normal
213 * sized packets. Jumbo packets consume 5 Rx buffers for a full-sized 213 * sized packets. Jumbo packets consume 5 Rx buffers for a full-sized
214 * packet. We allocate 256 receive descriptors, each with a 2k 214 * packet. We allocate 256 receive descriptors, each with a 2k
215 * buffer (MCLBYTES), which gives us room for 50 jumbo packets. 215 * buffer (MCLBYTES), which gives us room for 50 jumbo packets.
216 */ 216 */
217#define WM_NRXDESC 256 217#define WM_NRXDESC 256
218#define WM_NRXDESC_MASK (WM_NRXDESC - 1) 218#define WM_NRXDESC_MASK (WM_NRXDESC - 1)
219#define WM_NEXTRX(x) (((x) + 1) & WM_NRXDESC_MASK) 219#define WM_NEXTRX(x) (((x) + 1) & WM_NRXDESC_MASK)
220#define WM_PREVRX(x) (((x) - 1) & WM_NRXDESC_MASK) 220#define WM_PREVRX(x) (((x) - 1) & WM_NRXDESC_MASK)
221 221
222/* 222typedef union txdescs {
223 * Control structures are DMA'd to the i82542 chip. We allocate them in 223 wiseman_txdesc_t sctxu_txdescs[WM_NTXDESC_82544];
224 * a single clump that maps to a single DMA segment to make several things 224 nq_txdesc_t sctxu_nq_txdescs[WM_NTXDESC_82544];
225 * easier. 225} txdescs_t;
226 */ 
227struct wm_control_data_82544 { 
228 /* 
229 * The receive descriptors. 
230 */ 
231 wiseman_rxdesc_t wcd_rxdescs[WM_NRXDESC]; 
232 226
233 /* 227#define WM_CDTXOFF(x) (sizeof(wiseman_txdesc_t) * x)
234 * The transmit descriptors. Put these at the end, because 228#define WM_CDRXOFF(x) (sizeof(wiseman_rxdesc_t) * x)
235 * we might use a smaller number of them. 
236 */ 
237 union { 
238 wiseman_txdesc_t wcdu_txdescs[WM_NTXDESC_82544]; 
239 nq_txdesc_t wcdu_nq_txdescs[WM_NTXDESC_82544]; 
240 } wdc_u; 
241}; 
242 
243struct wm_control_data_82542 { 
244 wiseman_rxdesc_t wcd_rxdescs[WM_NRXDESC]; 
245 wiseman_txdesc_t wcd_txdescs[WM_NTXDESC_82542]; 
246}; 
247 
248#define WM_CDOFF(x) offsetof(struct wm_control_data_82544, x) 
249#define WM_CDTXOFF(x) WM_CDOFF(wdc_u.wcdu_txdescs[(x)]) 
250#define WM_CDRXOFF(x) WM_CDOFF(wcd_rxdescs[(x)]) 
251 229
252/* 230/*
253 * Software state for transmit jobs. 231 * Software state for transmit jobs.
254 */ 232 */
255struct wm_txsoft { 233struct wm_txsoft {
256 struct mbuf *txs_mbuf; /* head of our mbuf chain */ 234 struct mbuf *txs_mbuf; /* head of our mbuf chain */
257 bus_dmamap_t txs_dmamap; /* our DMA map */ 235 bus_dmamap_t txs_dmamap; /* our DMA map */
258 int txs_firstdesc; /* first descriptor in packet */ 236 int txs_firstdesc; /* first descriptor in packet */
259 int txs_lastdesc; /* last descriptor in packet */ 237 int txs_lastdesc; /* last descriptor in packet */
260 int txs_ndesc; /* # of descriptors used */ 238 int txs_ndesc; /* # of descriptors used */
261}; 239};
262 240
263/* 241/*
@@ -336,37 +314,44 @@ struct wm_softc { @@ -336,37 +314,44 @@ struct wm_softc {
336 int sc_nvm_ver_minor; 314 int sc_nvm_ver_minor;
337 int sc_nvm_ver_build; 315 int sc_nvm_ver_build;
338 int sc_nvm_addrbits; /* NVM address bits */ 316 int sc_nvm_addrbits; /* NVM address bits */
339 unsigned int sc_nvm_wordsize; /* NVM word size */ 317 unsigned int sc_nvm_wordsize; /* NVM word size */
340 int sc_ich8_flash_base; 318 int sc_ich8_flash_base;
341 int sc_ich8_flash_bank_size; 319 int sc_ich8_flash_bank_size;
342 int sc_nvm_k1_enabled; 320 int sc_nvm_k1_enabled;
343 321
344 /* Software state for the transmit and receive descriptors. */ 322 /* Software state for the transmit and receive descriptors. */
345 int sc_txnum; /* must be a power of two */ 323 int sc_txnum; /* must be a power of two */
346 struct wm_txsoft sc_txsoft[WM_TXQUEUELEN_MAX]; 324 struct wm_txsoft sc_txsoft[WM_TXQUEUELEN_MAX];
347 struct wm_rxsoft sc_rxsoft[WM_NRXDESC]; 325 struct wm_rxsoft sc_rxsoft[WM_NRXDESC];
348 326
349 /* Control data structures. */ 327 /* TX control data structures. */
350 int sc_ntxdesc; /* must be a power of two */ 328 int sc_ntxdesc; /* must be a power of two */
351 struct wm_control_data_82544 *sc_control_data; 329 txdescs_t *sc_txdescs_u;
352 bus_dmamap_t sc_cddmamap; /* control data DMA map */ 330 bus_dmamap_t sc_txdesc_dmamap; /* control data DMA map */
353 bus_dma_segment_t sc_cd_seg; /* control data segment */ 331 bus_dma_segment_t sc_txdesc_seg;/* control data segment */
354 int sc_cd_rseg; /* real number of control segment */ 332 int sc_txdesc_rseg; /* real number of control segment */
355 size_t sc_cd_size; /* control data size */ 333 size_t sc_txdesc_size; /* control data size */
356#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 334#define sc_txdesc_dma sc_txdesc_dmamap->dm_segs[0].ds_addr
357#define sc_txdescs sc_control_data->wdc_u.wcdu_txdescs 335#define sc_txdescs sc_txdescs_u->sctxu_txdescs
358#define sc_nq_txdescs sc_control_data->wdc_u.wcdu_nq_txdescs 336#define sc_nq_txdescs sc_txdescs_u->sctxu_nq_txdescs
359#define sc_rxdescs sc_control_data->wcd_rxdescs 337
 338 /* RX control data structures. */
 339 wiseman_rxdesc_t *sc_rxdescs;
 340 bus_dmamap_t sc_rxdesc_dmamap; /* control data DMA map */
 341 bus_dma_segment_t sc_rxdesc_seg;/* control data segment */
 342 int sc_rxdesc_rseg; /* real number of control segment */
 343 size_t sc_rxdesc_size; /* control data size */
 344#define sc_rxdesc_dma sc_rxdesc_dmamap->dm_segs[0].ds_addr
360 345
361#ifdef WM_EVENT_COUNTERS 346#ifdef WM_EVENT_COUNTERS
362 /* Event counters. */ 347 /* Event counters. */
363 struct evcnt sc_ev_txsstall; /* Tx stalled due to no txs */ 348 struct evcnt sc_ev_txsstall; /* Tx stalled due to no txs */
364 struct evcnt sc_ev_txdstall; /* Tx stalled due to no txd */ 349 struct evcnt sc_ev_txdstall; /* Tx stalled due to no txd */
365 struct evcnt sc_ev_txfifo_stall;/* Tx FIFO stalls (82547) */ 350 struct evcnt sc_ev_txfifo_stall;/* Tx FIFO stalls (82547) */
366 struct evcnt sc_ev_txdw; /* Tx descriptor interrupts */ 351 struct evcnt sc_ev_txdw; /* Tx descriptor interrupts */
367 struct evcnt sc_ev_txqe; /* Tx queue empty interrupts */ 352 struct evcnt sc_ev_txqe; /* Tx queue empty interrupts */
368 struct evcnt sc_ev_rxintr; /* Rx interrupts */ 353 struct evcnt sc_ev_rxintr; /* Rx interrupts */
369 struct evcnt sc_ev_linkintr; /* Link interrupts */ 354 struct evcnt sc_ev_linkintr; /* Link interrupts */
370 355
371 struct evcnt sc_ev_rxipsum; /* IP checksums checked in-bound */ 356 struct evcnt sc_ev_rxipsum; /* IP checksums checked in-bound */
372 struct evcnt sc_ev_rxtusum; /* TCP/UDP cksums checked in-bound */ 357 struct evcnt sc_ev_rxtusum; /* TCP/UDP cksums checked in-bound */
@@ -483,28 +468,28 @@ do { \ @@ -483,28 +468,28 @@ do { \
483#define CSR_WRITE_FLUSH(sc) \ 468#define CSR_WRITE_FLUSH(sc) \
484 (void) CSR_READ((sc), WMREG_STATUS) 469 (void) CSR_READ((sc), WMREG_STATUS)
485 470
486#define ICH8_FLASH_READ32(sc, reg) \ 471#define ICH8_FLASH_READ32(sc, reg) \
487 bus_space_read_4((sc)->sc_flasht, (sc)->sc_flashh, (reg)) 472 bus_space_read_4((sc)->sc_flasht, (sc)->sc_flashh, (reg))
488#define ICH8_FLASH_WRITE32(sc, reg, data) \ 473#define ICH8_FLASH_WRITE32(sc, reg, data) \
489 bus_space_write_4((sc)->sc_flasht, (sc)->sc_flashh, (reg), (data)) 474 bus_space_write_4((sc)->sc_flasht, (sc)->sc_flashh, (reg), (data))
490 475
491#define ICH8_FLASH_READ16(sc, reg) \ 476#define ICH8_FLASH_READ16(sc, reg) \
492 bus_space_read_2((sc)->sc_flasht, (sc)->sc_flashh, (reg)) 477 bus_space_read_2((sc)->sc_flasht, (sc)->sc_flashh, (reg))
493#define ICH8_FLASH_WRITE16(sc, reg, data) \ 478#define ICH8_FLASH_WRITE16(sc, reg, data) \
494 bus_space_write_2((sc)->sc_flasht, (sc)->sc_flashh, (reg), (data)) 479 bus_space_write_2((sc)->sc_flasht, (sc)->sc_flashh, (reg), (data))
495 480
496#define WM_CDTXADDR(sc, x) ((sc)->sc_cddma + WM_CDTXOFF((x))) 481#define WM_CDTXADDR(sc, x) ((sc)->sc_txdesc_dma + WM_CDTXOFF((x)))
497#define WM_CDRXADDR(sc, x) ((sc)->sc_cddma + WM_CDRXOFF((x))) 482#define WM_CDRXADDR(sc, x) ((sc)->sc_rxdesc_dma + WM_CDRXOFF((x)))
498 483
499#define WM_CDTXADDR_LO(sc, x) (WM_CDTXADDR((sc), (x)) & 0xffffffffU) 484#define WM_CDTXADDR_LO(sc, x) (WM_CDTXADDR((sc), (x)) & 0xffffffffU)
500#define WM_CDTXADDR_HI(sc, x) \ 485#define WM_CDTXADDR_HI(sc, x) \
501 (sizeof(bus_addr_t) == 8 ? \ 486 (sizeof(bus_addr_t) == 8 ? \
502 (uint64_t)WM_CDTXADDR((sc), (x)) >> 32 : 0) 487 (uint64_t)WM_CDTXADDR((sc), (x)) >> 32 : 0)
503 488
504#define WM_CDRXADDR_LO(sc, x) (WM_CDRXADDR((sc), (x)) & 0xffffffffU) 489#define WM_CDRXADDR_LO(sc, x) (WM_CDRXADDR((sc), (x)) & 0xffffffffU)
505#define WM_CDRXADDR_HI(sc, x) \ 490#define WM_CDRXADDR_HI(sc, x) \
506 (sizeof(bus_addr_t) == 8 ? \ 491 (sizeof(bus_addr_t) == 8 ? \
507 (uint64_t)WM_CDRXADDR((sc), (x)) >> 32 : 0) 492 (uint64_t)WM_CDRXADDR((sc), (x)) >> 32 : 0)
508 493
509/* 494/*
510 * Register read/write functions. 495 * Register read/write functions.
@@ -556,28 +541,30 @@ static uint32_t wm_rxpbs_adjust_82580(ui @@ -556,28 +541,30 @@ static uint32_t wm_rxpbs_adjust_82580(ui
556static void wm_reset(struct wm_softc *); 541static void wm_reset(struct wm_softc *);
557static int wm_add_rxbuf(struct wm_softc *, int); 542static int wm_add_rxbuf(struct wm_softc *, int);
558static void wm_rxdrain(struct wm_softc *); 543static void wm_rxdrain(struct wm_softc *);
559static int wm_init(struct ifnet *); 544static int wm_init(struct ifnet *);
560static int wm_init_locked(struct ifnet *); 545static int wm_init_locked(struct ifnet *);
561static void wm_stop(struct ifnet *, int); 546static void wm_stop(struct ifnet *, int);
562static void wm_stop_locked(struct ifnet *, int); 547static void wm_stop_locked(struct ifnet *, int);
563static int wm_tx_offload(struct wm_softc *, struct wm_txsoft *, 548static int wm_tx_offload(struct wm_softc *, struct wm_txsoft *,
564 uint32_t *, uint8_t *); 549 uint32_t *, uint8_t *);
565static void wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *); 550static void wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *);
566static void wm_82547_txfifo_stall(void *); 551static void wm_82547_txfifo_stall(void *);
567static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *); 552static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *);
568/* DMA related */ 553/* DMA related */
569static int wm_alloc_descs(struct wm_softc *); 554static int wm_alloc_tx_descs(struct wm_softc *);
570static void wm_free_descs(struct wm_softc *); 555static void wm_free_tx_descs(struct wm_softc *);
 556static int wm_alloc_rx_descs(struct wm_softc *);
 557static void wm_free_rx_descs(struct wm_softc *);
571static int wm_alloc_tx_buffer(struct wm_softc *); 558static int wm_alloc_tx_buffer(struct wm_softc *);
572static void wm_free_tx_buffer(struct wm_softc *); 559static void wm_free_tx_buffer(struct wm_softc *);
573static int wm_alloc_rx_buffer(struct wm_softc *); 560static int wm_alloc_rx_buffer(struct wm_softc *);
574static void wm_free_rx_buffer(struct wm_softc *); 561static void wm_free_rx_buffer(struct wm_softc *);
575static int wm_alloc_txrx_queues(struct wm_softc *); 562static int wm_alloc_txrx_queues(struct wm_softc *);
576static void wm_free_txrx_queues(struct wm_softc *); 563static void wm_free_txrx_queues(struct wm_softc *);
577/* Start */ 564/* Start */
578static void wm_start(struct ifnet *); 565static void wm_start(struct ifnet *);
579static void wm_start_locked(struct ifnet *); 566static void wm_start_locked(struct ifnet *);
580static int wm_nq_tx_offload(struct wm_softc *, struct wm_txsoft *, 567static int wm_nq_tx_offload(struct wm_softc *, struct wm_txsoft *,
581 uint32_t *, uint32_t *, bool *); 568 uint32_t *, uint32_t *, bool *);
582static void wm_nq_start(struct ifnet *); 569static void wm_nq_start(struct ifnet *);
583static void wm_nq_start_locked(struct ifnet *); 570static void wm_nq_start_locked(struct ifnet *);
@@ -1336,43 +1323,43 @@ wm_set_dma_addr(volatile wiseman_addr_t  @@ -1336,43 +1323,43 @@ wm_set_dma_addr(volatile wiseman_addr_t
1336 else 1323 else
1337 wa->wa_high = 0; 1324 wa->wa_high = 0;
1338} 1325}
1339 1326
1340/* 1327/*
1341 * Descriptor sync/init functions. 1328 * Descriptor sync/init functions.
1342 */ 1329 */
1343static inline void 1330static inline void
1344wm_cdtxsync(struct wm_softc *sc, int start, int num, int ops) 1331wm_cdtxsync(struct wm_softc *sc, int start, int num, int ops)
1345{ 1332{
1346 1333
1347 /* If it will wrap around, sync to the end of the ring. */ 1334 /* If it will wrap around, sync to the end of the ring. */
1348 if ((start + num) > WM_NTXDESC(sc)) { 1335 if ((start + num) > WM_NTXDESC(sc)) {
1349 bus_dmamap_sync(sc->sc_dmat, sc->sc_cddmamap, 1336 bus_dmamap_sync(sc->sc_dmat, sc->sc_txdesc_dmamap,
1350 WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) * 1337 WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) *
1351 (WM_NTXDESC(sc) - start), ops); 1338 (WM_NTXDESC(sc) - start), ops);
1352 num -= (WM_NTXDESC(sc) - start); 1339 num -= (WM_NTXDESC(sc) - start);
1353 start = 0; 1340 start = 0;
1354 } 1341 }
1355 1342
1356 /* Now sync whatever is left. */ 1343 /* Now sync whatever is left. */
1357 bus_dmamap_sync(sc->sc_dmat, sc->sc_cddmamap, 1344 bus_dmamap_sync(sc->sc_dmat, sc->sc_txdesc_dmamap,
1358 WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) * num, ops); 1345 WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) * num, ops);
1359} 1346}
1360 1347
1361static inline void 1348static inline void
1362wm_cdrxsync(struct wm_softc *sc, int start, int ops) 1349wm_cdrxsync(struct wm_softc *sc, int start, int ops)
1363{ 1350{
1364 1351
1365 bus_dmamap_sync(sc->sc_dmat, sc->sc_cddmamap, 1352 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxdesc_dmamap,
1366 WM_CDRXOFF(start), sizeof(wiseman_rxdesc_t), ops); 1353 WM_CDRXOFF(start), sizeof(wiseman_rxdesc_t), ops);
1367} 1354}
1368 1355
1369static inline void 1356static inline void
1370wm_init_rxdesc(struct wm_softc *sc, int start) 1357wm_init_rxdesc(struct wm_softc *sc, int start)
1371{ 1358{
1372 struct wm_rxsoft *rxs = &sc->sc_rxsoft[start]; 1359 struct wm_rxsoft *rxs = &sc->sc_rxsoft[start];
1373 wiseman_rxdesc_t *rxd = &sc->sc_rxdescs[start]; 1360 wiseman_rxdesc_t *rxd = &sc->sc_rxdescs[start];
1374 struct mbuf *m = rxs->rxs_mbuf; 1361 struct mbuf *m = rxs->rxs_mbuf;
1375 1362
1376 /* 1363 /*
1377 * Note: We scoot the packet forward 2 bytes in the buffer 1364 * Note: We scoot the packet forward 2 bytes in the buffer
1378 * so that the payload after the Ethernet header is aligned 1365 * so that the payload after the Ethernet header is aligned
@@ -5086,100 +5073,175 @@ wm_82547_txfifo_bugchk(struct wm_softc * @@ -5086,100 +5073,175 @@ wm_82547_txfifo_bugchk(struct wm_softc *
5086 callout_schedule(&sc->sc_txfifo_ch, 1); 5073 callout_schedule(&sc->sc_txfifo_ch, 1);
5087 return 1; 5074 return 1;
5088 } 5075 }
5089 5076
5090 send_packet: 5077 send_packet:
5091 sc->sc_txfifo_head += len; 5078 sc->sc_txfifo_head += len;
5092 if (sc->sc_txfifo_head >= sc->sc_txfifo_size) 5079 if (sc->sc_txfifo_head >= sc->sc_txfifo_size)
5093 sc->sc_txfifo_head -= sc->sc_txfifo_size; 5080 sc->sc_txfifo_head -= sc->sc_txfifo_size;
5094 5081
5095 return 0; 5082 return 0;
5096} 5083}
5097 5084
5098static int 5085static int
5099wm_alloc_descs(struct wm_softc *sc) 5086wm_alloc_tx_descs(struct wm_softc *sc)
 5087{
 5088 int error;
 5089
 5090 /*
 5091 * Allocate the control data structures, and create and load the
 5092 * DMA map for it.
 5093 *
 5094 * NOTE: All Tx descriptors must be in the same 4G segment of
 5095 * memory. So must Rx descriptors. We simplify by allocating
 5096 * both sets within the same 4G segment.
 5097 */
 5098 if (sc->sc_type < WM_T_82544) {
 5099 WM_NTXDESC(sc) = WM_NTXDESC_82542;
 5100 sc->sc_txdesc_size = sizeof(wiseman_txdesc_t) * WM_NTXDESC(sc);
 5101 } else {
 5102 WM_NTXDESC(sc) = WM_NTXDESC_82544;
 5103 sc->sc_txdesc_size = sizeof(txdescs_t);
 5104 }
 5105
 5106 if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_txdesc_size, PAGE_SIZE,
 5107 (bus_size_t) 0x100000000ULL, &sc->sc_txdesc_seg, 1,
 5108 &sc->sc_txdesc_rseg, 0)) != 0) {
 5109 aprint_error_dev(sc->sc_dev,
 5110 "unable to allocate TX control data, error = %d\n",
 5111 error);
 5112 goto fail_0;
 5113 }
 5114
 5115 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_txdesc_seg,
 5116 sc->sc_txdesc_rseg, sc->sc_txdesc_size,
 5117 (void **)&sc->sc_txdescs_u, BUS_DMA_COHERENT)) != 0) {
 5118 aprint_error_dev(sc->sc_dev,
 5119 "unable to map TX control data, error = %d\n", error);
 5120 goto fail_1;
 5121 }
 5122
 5123 if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_txdesc_size, 1,
 5124 sc->sc_txdesc_size, 0, 0, &sc->sc_txdesc_dmamap)) != 0) {
 5125 aprint_error_dev(sc->sc_dev,
 5126 "unable to create TX control data DMA map, error = %d\n",
 5127 error);
 5128 goto fail_2;
 5129 }
 5130
 5131 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_txdesc_dmamap,
 5132 sc->sc_txdescs_u, sc->sc_txdesc_size, NULL, 0)) != 0) {
 5133 aprint_error_dev(sc->sc_dev,
 5134 "unable to load TX control data DMA map, error = %d\n",
 5135 error);
 5136 goto fail_3;
 5137 }
 5138
 5139 return 0;
 5140
 5141 fail_3:
 5142 bus_dmamap_destroy(sc->sc_dmat, sc->sc_txdesc_dmamap);
 5143 fail_2:
 5144 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_txdescs_u,
 5145 sc->sc_txdesc_size);
 5146 fail_1:
 5147 bus_dmamem_free(sc->sc_dmat, &sc->sc_txdesc_seg, sc->sc_txdesc_rseg);
 5148 fail_0:
 5149 return error;
 5150}
 5151
 5152static void
 5153wm_free_tx_descs(struct wm_softc *sc)
 5154{
 5155
 5156 bus_dmamap_unload(sc->sc_dmat, sc->sc_txdesc_dmamap);
 5157 bus_dmamap_destroy(sc->sc_dmat, sc->sc_txdesc_dmamap);
 5158 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_txdescs_u,
 5159 sc->sc_txdesc_size);
 5160 bus_dmamem_free(sc->sc_dmat, &sc->sc_txdesc_seg, sc->sc_txdesc_rseg);
 5161}
 5162
 5163static int
 5164wm_alloc_rx_descs(struct wm_softc *sc)
5100{ 5165{
5101 int error; 5166 int error;
5102 5167
5103 /* 5168 /*
5104 * Allocate the control data structures, and create and load the 5169 * Allocate the control data structures, and create and load the
5105 * DMA map for it. 5170 * DMA map for it.
5106 * 5171 *
5107 * NOTE: All Tx descriptors must be in the same 4G segment of 5172 * NOTE: All Tx descriptors must be in the same 4G segment of
5108 * memory. So must Rx descriptors. We simplify by allocating 5173 * memory. So must Rx descriptors. We simplify by allocating
5109 * both sets within the same 4G segment. 5174 * both sets within the same 4G segment.
5110 */ 5175 */
5111 WM_NTXDESC(sc) = sc->sc_type < WM_T_82544 ? 5176 sc->sc_rxdesc_size = sizeof(wiseman_rxdesc_t) * WM_NRXDESC;
5112 WM_NTXDESC_82542 : WM_NTXDESC_82544; 5177 if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_rxdesc_size, PAGE_SIZE,
5113 sc->sc_cd_size = sc->sc_type < WM_T_82544 ? 5178 (bus_size_t) 0x100000000ULL, &sc->sc_rxdesc_seg, 1,
5114 sizeof(struct wm_control_data_82542) : 5179 &sc->sc_rxdesc_rseg, 0)) != 0) {
5115 sizeof(struct wm_control_data_82544); 
5116 if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_cd_size, PAGE_SIZE, 
5117 (bus_size_t) 0x100000000ULL, &sc->sc_cd_seg, 1, 
5118 &sc->sc_cd_rseg, 0)) != 0) { 
5119 aprint_error_dev(sc->sc_dev, 5180 aprint_error_dev(sc->sc_dev,
5120 "unable to allocate control data, error = %d\n", 5181 "unable to allocate RX control data, error = %d\n",
5121 error); 5182 error);
5122 goto fail_0; 5183 goto fail_0;
5123 } 5184 }
5124 5185
5125 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cd_seg, 5186 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_rxdesc_seg,
5126 sc->sc_cd_rseg, sc->sc_cd_size, 5187 sc->sc_rxdesc_rseg, sc->sc_rxdesc_size,
5127 (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) { 5188 (void **)&sc->sc_rxdescs, BUS_DMA_COHERENT)) != 0) {
5128 aprint_error_dev(sc->sc_dev, 5189 aprint_error_dev(sc->sc_dev,
5129 "unable to map control data, error = %d\n", error); 5190 "unable to map RX control data, error = %d\n", error);
5130 goto fail_1; 5191 goto fail_1;
5131 } 5192 }
5132 5193
5133 if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_cd_size, 1, 5194 if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_rxdesc_size, 1,
5134 sc->sc_cd_size, 0, 0, &sc->sc_cddmamap)) != 0) { 5195 sc->sc_rxdesc_size, 0, 0, &sc->sc_rxdesc_dmamap)) != 0) {
5135 aprint_error_dev(sc->sc_dev, 5196 aprint_error_dev(sc->sc_dev,
5136 "unable to create control data DMA map, error = %d\n", 5197 "unable to create RX control data DMA map, error = %d\n",
5137 error); 5198 error);
5138 goto fail_2; 5199 goto fail_2;
5139 } 5200 }
5140 5201
5141 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, 5202 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_rxdesc_dmamap,
5142 sc->sc_control_data, sc->sc_cd_size, NULL, 0)) != 0) { 5203 sc->sc_rxdescs, sc->sc_rxdesc_size, NULL, 0)) != 0) {
5143 aprint_error_dev(sc->sc_dev, 5204 aprint_error_dev(sc->sc_dev,
5144 "unable to load control data DMA map, error = %d\n", 5205 "unable to load RX control data DMA map, error = %d\n",
5145 error); 5206 error);
5146 goto fail_3; 5207 goto fail_3;
5147 } 5208 }
5148 5209
5149 return 0; 5210 return 0;
5150 5211
5151 fail_3: 5212 fail_3:
5152 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); 5213 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxdesc_dmamap);
5153 fail_2: 5214 fail_2:
5154 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, 5215 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_rxdescs,
5155 sc->sc_cd_size); 5216 sc->sc_rxdesc_size);
5156 fail_1: 5217 fail_1:
5157 bus_dmamem_free(sc->sc_dmat, &sc->sc_cd_seg, sc->sc_cd_rseg); 5218 bus_dmamem_free(sc->sc_dmat, &sc->sc_rxdesc_seg, sc->sc_rxdesc_rseg);
5158 fail_0: 5219 fail_0:
5159 return error; 5220 return error;
5160} 5221}
5161 5222
5162static void 5223static void
5163wm_free_descs(struct wm_softc *sc) 5224wm_free_rx_descs(struct wm_softc *sc)
5164{ 5225{
5165 5226
5166 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); 5227 bus_dmamap_unload(sc->sc_dmat, sc->sc_rxdesc_dmamap);
5167 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); 5228 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxdesc_dmamap);
5168 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, 5229 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_rxdescs,
5169 sc->sc_cd_size); 5230 sc->sc_rxdesc_size);
5170 bus_dmamem_free(sc->sc_dmat, &sc->sc_cd_seg, sc->sc_cd_rseg); 5231 bus_dmamem_free(sc->sc_dmat, &sc->sc_rxdesc_seg, sc->sc_rxdesc_rseg);
5171} 5232}
5172 5233
 5234
5173static int 5235static int
5174wm_alloc_tx_buffer(struct wm_softc *sc) 5236wm_alloc_tx_buffer(struct wm_softc *sc)
5175{ 5237{
5176 int i, error; 5238 int i, error;
5177 5239
5178 /* Create the transmit buffer DMA maps. */ 5240 /* Create the transmit buffer DMA maps. */
5179 WM_TXQUEUELEN(sc) = 5241 WM_TXQUEUELEN(sc) =
5180 (sc->sc_type == WM_T_82547 || sc->sc_type == WM_T_82547_2) ? 5242 (sc->sc_type == WM_T_82547 || sc->sc_type == WM_T_82547_2) ?
5181 WM_TXQUEUELEN_MAX_82547 : WM_TXQUEUELEN_MAX; 5243 WM_TXQUEUELEN_MAX_82547 : WM_TXQUEUELEN_MAX;
5182 for (i = 0; i < WM_TXQUEUELEN(sc); i++) { 5244 for (i = 0; i < WM_TXQUEUELEN(sc); i++) {
5183 if ((error = bus_dmamap_create(sc->sc_dmat, WM_MAXTXDMA, 5245 if ((error = bus_dmamap_create(sc->sc_dmat, WM_MAXTXDMA,
5184 WM_NTXSEGS, WTX_MAX_LEN, 0, 0, 5246 WM_NTXSEGS, WTX_MAX_LEN, 0, 0,
5185 &sc->sc_txsoft[i].txs_dmamap)) != 0) { 5247 &sc->sc_txsoft[i].txs_dmamap)) != 0) {
@@ -5253,59 +5315,72 @@ wm_free_rx_buffer(struct wm_softc *sc) @@ -5253,59 +5315,72 @@ wm_free_rx_buffer(struct wm_softc *sc)
5253 sc->sc_rxsoft[i].rxs_dmamap); 5315 sc->sc_rxsoft[i].rxs_dmamap);
5254 } 5316 }
5255} 5317}
5256 5318
5257/* 5319/*
5258 * wm_alloc_quques: 5320 * wm_alloc_quques:
5259 * Allocate {tx,rx}descs and {tx,rx} buffers 5321 * Allocate {tx,rx}descs and {tx,rx} buffers
5260 */ 5322 */
5261static int 5323static int
5262wm_alloc_txrx_queues(struct wm_softc *sc) 5324wm_alloc_txrx_queues(struct wm_softc *sc)
5263{ 5325{
5264 int error; 5326 int error;
5265 5327
5266 error = wm_alloc_descs(sc); 5328 /*
 5329 * For transmission
 5330 */
 5331 error = wm_alloc_tx_descs(sc);
5267 if (error) 5332 if (error)
5268 goto fail_0; 5333 goto fail_0;
5269 5334
5270 error = wm_alloc_tx_buffer(sc); 5335 error = wm_alloc_tx_buffer(sc);
5271 if (error) 5336 if (error)
5272 goto fail_1; 5337 goto fail_1;
5273 5338
5274 error = wm_alloc_rx_buffer(sc); 5339 /*
 5340 * For recieve
 5341 */
 5342 error = wm_alloc_rx_descs(sc);
5275 if (error) 5343 if (error)
5276 goto fail_2; 5344 goto fail_2;
5277 5345
 5346 error = wm_alloc_rx_buffer(sc);
 5347 if (error)
 5348 goto fail_3;
 5349
5278 return 0; 5350 return 0;
5279 5351
 5352fail_3:
 5353 wm_free_rx_descs(sc);
5280fail_2: 5354fail_2:
5281 wm_free_tx_buffer(sc); 5355 wm_free_tx_buffer(sc);
5282fail_1: 5356fail_1:
5283 wm_free_descs(sc); 5357 wm_free_tx_descs(sc);
5284fail_0: 5358fail_0:
5285 return error; 5359 return error;
5286} 5360}
5287 5361
5288/* 5362/*
5289 * wm_free_quques: 5363 * wm_free_quques:
5290 * Free {tx,rx}descs and {tx,rx} buffers 5364 * Free {tx,rx}descs and {tx,rx} buffers
5291 */ 5365 */
5292static void 5366static void
5293wm_free_txrx_queues(struct wm_softc *sc) 5367wm_free_txrx_queues(struct wm_softc *sc)
5294{ 5368{
5295 5369
5296 wm_free_rx_buffer(sc); 5370 wm_free_rx_buffer(sc);
 5371 wm_free_rx_descs(sc);
5297 wm_free_tx_buffer(sc); 5372 wm_free_tx_buffer(sc);
5298 wm_free_descs(sc); 5373 wm_free_tx_descs(sc);
5299} 5374}
5300 5375
5301/* 5376/*
5302 * wm_start: [ifnet interface function] 5377 * wm_start: [ifnet interface function]
5303 * 5378 *
5304 * Start packet transmission on the interface. 5379 * Start packet transmission on the interface.
5305 */ 5380 */
5306static void 5381static void
5307wm_start(struct ifnet *ifp) 5382wm_start(struct ifnet *ifp)
5308{ 5383{
5309 struct wm_softc *sc = ifp->if_softc; 5384 struct wm_softc *sc = ifp->if_softc;
5310 5385
5311 WM_TX_LOCK(sc); 5386 WM_TX_LOCK(sc);