Tue Oct 13 08:14:27 2015 UTC ()
refactor: separate discriptors initialization and registers initialization


(knakahara)
diff -r1.357 -r1.358 src/sys/dev/pci/if_wm.c

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

--- src/sys/dev/pci/if_wm.c 2015/10/13 08:11:31 1.357
+++ src/sys/dev/pci/if_wm.c 2015/10/13 08:14:27 1.358
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_wm.c,v 1.357 2015/10/13 08:11:31 knakahara Exp $ */ 1/* $NetBSD: if_wm.c,v 1.358 2015/10/13 08:14:27 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.357 2015/10/13 08:11:31 knakahara Exp $"); 86__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.358 2015/10/13 08:14:27 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/kmem.h> 97#include <sys/kmem.h>
98#include <sys/kernel.h> 98#include <sys/kernel.h>
99#include <sys/socket.h> 99#include <sys/socket.h>
@@ -572,29 +572,30 @@ static void wm_rxdrain(struct wm_softc * @@ -572,29 +572,30 @@ static void wm_rxdrain(struct wm_softc *
572static int wm_init(struct ifnet *); 572static int wm_init(struct ifnet *);
573static int wm_init_locked(struct ifnet *); 573static int wm_init_locked(struct ifnet *);
574static void wm_stop(struct ifnet *, int); 574static void wm_stop(struct ifnet *, int);
575static void wm_stop_locked(struct ifnet *, int); 575static void wm_stop_locked(struct ifnet *, int);
576static int wm_tx_offload(struct wm_softc *, struct wm_txsoft *, 576static int wm_tx_offload(struct wm_softc *, struct wm_txsoft *,
577 uint32_t *, uint8_t *); 577 uint32_t *, uint8_t *);
578static void wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *); 578static void wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *);
579static void wm_82547_txfifo_stall(void *); 579static void wm_82547_txfifo_stall(void *);
580static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *); 580static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *);
581/* DMA related */ 581/* DMA related */
582static int wm_alloc_tx_descs(struct wm_softc *); 582static int wm_alloc_tx_descs(struct wm_softc *);
583static void wm_free_tx_descs(struct wm_softc *); 583static void wm_free_tx_descs(struct wm_softc *);
584static void wm_init_tx_descs(struct wm_softc *); 584static void wm_init_tx_descs(struct wm_softc *);
 585static void wm_init_tx_regs(struct wm_softc *);
585static int wm_alloc_rx_descs(struct wm_softc *); 586static int wm_alloc_rx_descs(struct wm_softc *);
586static void wm_free_rx_descs(struct wm_softc *); 587static void wm_free_rx_descs(struct wm_softc *);
587static void wm_init_rx_descs(struct wm_softc *); 588static void wm_init_rx_regs(struct wm_softc *);
588static int wm_alloc_tx_buffer(struct wm_softc *); 589static int wm_alloc_tx_buffer(struct wm_softc *);
589static void wm_free_tx_buffer(struct wm_softc *); 590static void wm_free_tx_buffer(struct wm_softc *);
590static void wm_init_tx_buffer(struct wm_softc *); 591static void wm_init_tx_buffer(struct wm_softc *);
591static int wm_alloc_rx_buffer(struct wm_softc *); 592static int wm_alloc_rx_buffer(struct wm_softc *);
592static void wm_free_rx_buffer(struct wm_softc *); 593static void wm_free_rx_buffer(struct wm_softc *);
593static int wm_init_rx_buffer(struct wm_softc *); 594static int wm_init_rx_buffer(struct wm_softc *);
594static void wm_init_tx_queue(struct wm_softc *); 595static void wm_init_tx_queue(struct wm_softc *);
595static int wm_init_rx_queue(struct wm_softc *); 596static int wm_init_rx_queue(struct wm_softc *);
596static int wm_alloc_txrx_queues(struct wm_softc *); 597static int wm_alloc_txrx_queues(struct wm_softc *);
597static void wm_free_txrx_queues(struct wm_softc *); 598static void wm_free_txrx_queues(struct wm_softc *);
598static int wm_init_txrx_queues(struct wm_softc *); 599static int wm_init_txrx_queues(struct wm_softc *);
599/* Start */ 600/* Start */
600static void wm_start(struct ifnet *); 601static void wm_start(struct ifnet *);
@@ -5355,26 +5356,34 @@ wm_free_txrx_queues(struct wm_softc *sc) @@ -5355,26 +5356,34 @@ wm_free_txrx_queues(struct wm_softc *sc)
5355static void 5356static void
5356wm_init_tx_descs(struct wm_softc *sc) 5357wm_init_tx_descs(struct wm_softc *sc)
5357{ 5358{
5358 struct wm_txqueue *txq = sc->sc_txq; 5359 struct wm_txqueue *txq = sc->sc_txq;
5359 5360
5360 KASSERT(WM_TX_LOCKED(txq)); 5361 KASSERT(WM_TX_LOCKED(txq));
5361 5362
5362 /* Initialize the transmit descriptor ring. */ 5363 /* Initialize the transmit descriptor ring. */
5363 memset(txq->txq_descs, 0, WM_TXDESCSIZE(txq)); 5364 memset(txq->txq_descs, 0, WM_TXDESCSIZE(txq));
5364 wm_cdtxsync(sc, 0, WM_NTXDESC(txq), 5365 wm_cdtxsync(sc, 0, WM_NTXDESC(txq),
5365 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 5366 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
5366 txq->txq_free = WM_NTXDESC(txq); 5367 txq->txq_free = WM_NTXDESC(txq);
5367 txq->txq_next = 0; 5368 txq->txq_next = 0;
 5369}
 5370
 5371static void
 5372wm_init_tx_regs(struct wm_softc *sc)
 5373{
 5374 struct wm_txqueue *txq = sc->sc_txq;
 5375
 5376 KASSERT(WM_TX_LOCKED(txq));
5368 5377
5369 if (sc->sc_type < WM_T_82543) { 5378 if (sc->sc_type < WM_T_82543) {
5370 CSR_WRITE(sc, WMREG_OLD_TDBAH, WM_CDTXADDR_HI(txq, 0)); 5379 CSR_WRITE(sc, WMREG_OLD_TDBAH, WM_CDTXADDR_HI(txq, 0));
5371 CSR_WRITE(sc, WMREG_OLD_TDBAL, WM_CDTXADDR_LO(txq, 0)); 5380 CSR_WRITE(sc, WMREG_OLD_TDBAL, WM_CDTXADDR_LO(txq, 0));
5372 CSR_WRITE(sc, WMREG_OLD_TDLEN, WM_TXDESCSIZE(txq)); 5381 CSR_WRITE(sc, WMREG_OLD_TDLEN, WM_TXDESCSIZE(txq));
5373 CSR_WRITE(sc, WMREG_OLD_TDH, 0); 5382 CSR_WRITE(sc, WMREG_OLD_TDH, 0);
5374 CSR_WRITE(sc, WMREG_OLD_TDT, 0); 5383 CSR_WRITE(sc, WMREG_OLD_TDT, 0);
5375 CSR_WRITE(sc, WMREG_OLD_TIDV, 128); 5384 CSR_WRITE(sc, WMREG_OLD_TIDV, 128);
5376 } else { 5385 } else {
5377 CSR_WRITE(sc, WMREG_TDBAH, WM_CDTXADDR_HI(txq, 0)); 5386 CSR_WRITE(sc, WMREG_TDBAH, WM_CDTXADDR_HI(txq, 0));
5378 CSR_WRITE(sc, WMREG_TDBAL, WM_CDTXADDR_LO(txq, 0)); 5387 CSR_WRITE(sc, WMREG_TDBAL, WM_CDTXADDR_LO(txq, 0));
5379 CSR_WRITE(sc, WMREG_TDLEN, WM_TXDESCSIZE(txq)); 5388 CSR_WRITE(sc, WMREG_TDLEN, WM_TXDESCSIZE(txq));
5380 CSR_WRITE(sc, WMREG_TDH, 0); 5389 CSR_WRITE(sc, WMREG_TDH, 0);
@@ -5388,28 +5397,26 @@ wm_init_tx_descs(struct wm_softc *sc) @@ -5388,28 +5397,26 @@ wm_init_tx_descs(struct wm_softc *sc)
5388 | TXDCTL_PTHRESH(0) | TXDCTL_HTHRESH(0) 5397 | TXDCTL_PTHRESH(0) | TXDCTL_HTHRESH(0)
5389 | TXDCTL_WTHRESH(0)); 5398 | TXDCTL_WTHRESH(0));
5390 else { 5399 else {
5391 /* ITR / 4 */ 5400 /* ITR / 4 */
5392 CSR_WRITE(sc, WMREG_TIDV, sc->sc_itr / 4); 5401 CSR_WRITE(sc, WMREG_TIDV, sc->sc_itr / 4);
5393 if (sc->sc_type >= WM_T_82540) { 5402 if (sc->sc_type >= WM_T_82540) {
5394 /* should be same */ 5403 /* should be same */
5395 CSR_WRITE(sc, WMREG_TADV, sc->sc_itr / 4); 5404 CSR_WRITE(sc, WMREG_TADV, sc->sc_itr / 4);
5396 } 5405 }
5397 5406
5398 CSR_WRITE(sc, WMREG_TDT, 0); 5407 CSR_WRITE(sc, WMREG_TDT, 0);
5399 CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_PTHRESH(0) | 5408 CSR_WRITE(sc, WMREG_TXDCTL(0), TXDCTL_PTHRESH(0) |
5400 TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0)); 5409 TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0));
5401 CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_PTHRESH(0) | 
5402 RXDCTL_HTHRESH(0) | RXDCTL_WTHRESH(1)); 
5403 } 5410 }
5404 } 5411 }
5405} 5412}
5406 5413
5407static void 5414static void
5408wm_init_tx_buffer(struct wm_softc *sc) 5415wm_init_tx_buffer(struct wm_softc *sc)
5409{ 5416{
5410 struct wm_txqueue *txq = sc->sc_txq; 5417 struct wm_txqueue *txq = sc->sc_txq;
5411 int i; 5418 int i;
5412 5419
5413 KASSERT(WM_TX_LOCKED(txq)); 5420 KASSERT(WM_TX_LOCKED(txq));
5414 5421
5415 /* Initialize the transmit job descriptors. */ 5422 /* Initialize the transmit job descriptors. */
@@ -5428,31 +5435,32 @@ wm_init_tx_queue(struct wm_softc *sc) @@ -5428,31 +5435,32 @@ wm_init_tx_queue(struct wm_softc *sc)
5428 KASSERT(WM_TX_LOCKED(txq)); 5435 KASSERT(WM_TX_LOCKED(txq));
5429 5436
5430 /* 5437 /*
5431 * Set up some register offsets that are different between 5438 * Set up some register offsets that are different between
5432 * the i82542 and the i82543 and later chips. 5439 * the i82542 and the i82543 and later chips.
5433 */ 5440 */
5434 if (sc->sc_type < WM_T_82543) { 5441 if (sc->sc_type < WM_T_82543) {
5435 txq->txq_tdt_reg = WMREG_OLD_TDT; 5442 txq->txq_tdt_reg = WMREG_OLD_TDT;
5436 } else { 5443 } else {
5437 txq->txq_tdt_reg = WMREG_TDT; 5444 txq->txq_tdt_reg = WMREG_TDT;
5438 } 5445 }
5439 5446
5440 wm_init_tx_descs(sc); 5447 wm_init_tx_descs(sc);
 5448 wm_init_tx_regs(sc);
5441 wm_init_tx_buffer(sc); 5449 wm_init_tx_buffer(sc);
5442} 5450}
5443 5451
5444static void 5452static void
5445wm_init_rx_descs(struct wm_softc *sc) 5453wm_init_rx_regs(struct wm_softc *sc)
5446{ 5454{
5447 struct wm_rxqueue *rxq = sc->sc_rxq; 5455 struct wm_rxqueue *rxq = sc->sc_rxq;
5448 5456
5449 KASSERT(WM_RX_LOCKED(rxq)); 5457 KASSERT(WM_RX_LOCKED(rxq));
5450 5458
5451 /* 5459 /*
5452 * Initialize the receive descriptor and receive job 5460 * Initialize the receive descriptor and receive job
5453 * descriptor rings. 5461 * descriptor rings.
5454 */ 5462 */
5455 if (sc->sc_type < WM_T_82543) { 5463 if (sc->sc_type < WM_T_82543) {
5456 CSR_WRITE(sc, WMREG_OLD_RDBAH0, WM_CDRXADDR_HI(rxq, 0)); 5464 CSR_WRITE(sc, WMREG_OLD_RDBAH0, WM_CDRXADDR_HI(rxq, 0));
5457 CSR_WRITE(sc, WMREG_OLD_RDBAL0, WM_CDRXADDR_LO(rxq, 0)); 5465 CSR_WRITE(sc, WMREG_OLD_RDBAL0, WM_CDRXADDR_LO(rxq, 0));
5458 CSR_WRITE(sc, WMREG_OLD_RDLEN0, 5466 CSR_WRITE(sc, WMREG_OLD_RDLEN0,
@@ -5476,26 +5484,28 @@ wm_init_rx_descs(struct wm_softc *sc) @@ -5476,26 +5484,28 @@ wm_init_rx_descs(struct wm_softc *sc)
5476 if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) { 5484 if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
5477 if (MCLBYTES & ((1 << SRRCTL_BSIZEPKT_SHIFT) - 1)) 5485 if (MCLBYTES & ((1 << SRRCTL_BSIZEPKT_SHIFT) - 1))
5478 panic("%s: MCLBYTES %d unsupported for i2575 or higher\n", __func__, MCLBYTES); 5486 panic("%s: MCLBYTES %d unsupported for i2575 or higher\n", __func__, MCLBYTES);
5479 CSR_WRITE(sc, WMREG_SRRCTL, SRRCTL_DESCTYPE_LEGACY 5487 CSR_WRITE(sc, WMREG_SRRCTL, SRRCTL_DESCTYPE_LEGACY
5480 | (MCLBYTES >> SRRCTL_BSIZEPKT_SHIFT)); 5488 | (MCLBYTES >> SRRCTL_BSIZEPKT_SHIFT));
5481 CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_QUEUE_ENABLE 5489 CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_QUEUE_ENABLE
5482 | RXDCTL_PTHRESH(16) | RXDCTL_HTHRESH(8) 5490 | RXDCTL_PTHRESH(16) | RXDCTL_HTHRESH(8)
5483 | RXDCTL_WTHRESH(1)); 5491 | RXDCTL_WTHRESH(1));
5484 } else { 5492 } else {
5485 CSR_WRITE(sc, WMREG_RDH, 0); 5493 CSR_WRITE(sc, WMREG_RDH, 0);
5486 CSR_WRITE(sc, WMREG_RDT, 0); 5494 CSR_WRITE(sc, WMREG_RDT, 0);
5487 CSR_WRITE(sc, WMREG_RDTR, 375 | RDTR_FPD); /* ITR/4 */ 5495 CSR_WRITE(sc, WMREG_RDTR, 375 | RDTR_FPD); /* ITR/4 */
5488 CSR_WRITE(sc, WMREG_RADV, 375); /* MUST be same */ 5496 CSR_WRITE(sc, WMREG_RADV, 375); /* MUST be same */
 5497 CSR_WRITE(sc, WMREG_RXDCTL, RXDCTL_PTHRESH(0) |
 5498 RXDCTL_HTHRESH(0) | RXDCTL_WTHRESH(1));
5489 } 5499 }
5490 } 5500 }
5491} 5501}
5492 5502
5493static int 5503static int
5494wm_init_rx_buffer(struct wm_softc *sc) 5504wm_init_rx_buffer(struct wm_softc *sc)
5495{ 5505{
5496 struct wm_rxqueue *rxq = sc->sc_rxq; 5506 struct wm_rxqueue *rxq = sc->sc_rxq;
5497 struct wm_rxsoft *rxs; 5507 struct wm_rxsoft *rxs;
5498 int error, i; 5508 int error, i;
5499 5509
5500 KASSERT(WM_RX_LOCKED(rxq)); 5510 KASSERT(WM_RX_LOCKED(rxq));
5501 5511
@@ -5537,27 +5547,27 @@ wm_init_rx_queue(struct wm_softc *sc) @@ -5537,27 +5547,27 @@ wm_init_rx_queue(struct wm_softc *sc)
5537 5547
5538 KASSERT(WM_RX_LOCKED(rxq)); 5548 KASSERT(WM_RX_LOCKED(rxq));
5539 5549
5540 /* 5550 /*
5541 * Set up some register offsets that are different between 5551 * Set up some register offsets that are different between
5542 * the i82542 and the i82543 and later chips. 5552 * the i82542 and the i82543 and later chips.
5543 */ 5553 */
5544 if (sc->sc_type < WM_T_82543) { 5554 if (sc->sc_type < WM_T_82543) {
5545 rxq->rxq_rdt_reg = WMREG_OLD_RDT0; 5555 rxq->rxq_rdt_reg = WMREG_OLD_RDT0;
5546 } else { 5556 } else {
5547 rxq->rxq_rdt_reg = WMREG_RDT; 5557 rxq->rxq_rdt_reg = WMREG_RDT;
5548 } 5558 }
5549 5559
5550 wm_init_rx_descs(sc); 5560 wm_init_rx_regs(sc);
5551 return wm_init_rx_buffer(sc); 5561 return wm_init_rx_buffer(sc);
5552} 5562}
5553 5563
5554/* 5564/*
5555 * wm_init_quques: 5565 * wm_init_quques:
5556 * Initialize {tx,rx}descs and {tx,rx} buffers 5566 * Initialize {tx,rx}descs and {tx,rx} buffers
5557 */ 5567 */
5558static int 5568static int
5559wm_init_txrx_queues(struct wm_softc *sc) 5569wm_init_txrx_queues(struct wm_softc *sc)
5560{ 5570{
5561 struct wm_txqueue *txq = sc->sc_txq; 5571 struct wm_txqueue *txq = sc->sc_txq;
5562 struct wm_rxqueue *rxq = sc->sc_rxq; 5572 struct wm_rxqueue *rxq = sc->sc_rxq;
5563 int error; 5573 int error;