Migrate e1000 to the IFLIB framework:
- em(4) igb(4) and lem(4) - deprecate the igb device from kernel configurations - create a symbolic link in /boot/kernel from if_em.ko to if_igb.ko Devices tested: - 82574L - I218-LM - 82546GB - 82579LM - I350 - I217 Please report problems to freebsd-net@freebsd.org Partial review from jhb and suggestions on how to *not* brick folks who originally would have lost their igbX device. Submitted by: mmacy@nextbsd.org MFC after: 2 weeks Relnotes: yes Sponsored by: Limelight Networks and Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D8299
This commit is contained in:
parent
72aca66b1d
commit
efab05d612
5
UPDATING
5
UPDATING
@ -51,6 +51,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
||||
|
||||
****************************** SPECIAL WARNING: ******************************
|
||||
|
||||
20170109:
|
||||
The igb(4), em(4) and lem(4) ethernet drivers are now implemented via
|
||||
IFLIB. If you have a custom kernel configuration that excludes em(4)
|
||||
but you use igb(4), you need to re-add em(4) to your custom configuration.
|
||||
|
||||
20161217:
|
||||
Clang, llvm, lldb, compiler-rt and libc++ have been upgraded to 3.9.1.
|
||||
Please see the 20141231 entry below for information about prerequisites
|
||||
|
@ -230,7 +230,6 @@ device puc # Multi I/O cards and multi-channel UARTs
|
||||
device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE
|
||||
device de # DEC/Intel DC21x4x (``Tulip'')
|
||||
device em # Intel PRO/1000 Gigabit Ethernet Family
|
||||
device igb # Intel PRO/1000 PCIE Server Gigabit Family
|
||||
device ix # Intel PRO/10GbE PCIE PF Ethernet
|
||||
device ixv # Intel PRO/10GbE PCIE VF Ethernet
|
||||
device ixl # Intel XL710 40Gbe PCIE Ethernet
|
||||
|
@ -120,7 +120,6 @@ device mii
|
||||
device miibus # MII bus support
|
||||
device awg # Allwinner EMAC Gigabit Ethernet
|
||||
device em # Intel PRO/1000 Gigabit Ethernet Family
|
||||
device igb # Intel PRO/1000 PCIE Server Gigabit Family
|
||||
device ix # Intel 10Gb Ethernet Family
|
||||
device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet
|
||||
device smc # SMSC LAN91C111
|
||||
|
@ -1972,7 +1972,6 @@ device xmphy # XaQti XMAC II
|
||||
# KNE110TX.
|
||||
# de: Digital Equipment DC21040
|
||||
# em: Intel Pro/1000 Gigabit Ethernet 82542, 82543, 82544 based adapters.
|
||||
# igb: Intel Pro/1000 PCI Express Gigabit Ethernet: 82575 and later adapters.
|
||||
# ep: 3Com 3C509, 3C529, 3C556, 3C562D, 3C563D, 3C572, 3C574X, 3C579, 3C589
|
||||
# and PC Card devices using these chipsets.
|
||||
# ex: Intel EtherExpress Pro/10 and other i82595-based adapters,
|
||||
@ -2145,7 +2144,6 @@ device cxgbe # Chelsio T4-T6 1/10/25/40/100 Gigabit Ethernet
|
||||
device cxgbev # Chelsio T4-T6 Virtual Functions
|
||||
device de # DEC/Intel DC21x4x (``Tulip'')
|
||||
device em # Intel Pro/1000 Gigabit Ethernet
|
||||
device igb # Intel Pro/1000 PCIE Gigabit Ethernet
|
||||
device ixgb # Intel Pro/10Gbe PCI-X Ethernet
|
||||
device ix # Intel Pro/10Gbe PCIE Ethernet
|
||||
device ixv # Intel Pro/10Gbe PCIE Ethernet VF
|
||||
|
@ -1572,43 +1572,43 @@ dev/eisa/eisa_if.m standard
|
||||
dev/eisa/eisaconf.c optional eisa
|
||||
dev/e1000/if_em.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/if_lem.c optional em \
|
||||
dev/e1000/em_txrx.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/if_igb.c optional igb \
|
||||
dev/e1000/igb_txrx.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_80003es2lan.c optional em | igb \
|
||||
dev/e1000/e1000_80003es2lan.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_82540.c optional em | igb \
|
||||
dev/e1000/e1000_82540.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_82541.c optional em | igb \
|
||||
dev/e1000/e1000_82541.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_82542.c optional em | igb \
|
||||
dev/e1000/e1000_82542.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_82543.c optional em | igb \
|
||||
dev/e1000/e1000_82543.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_82571.c optional em | igb \
|
||||
dev/e1000/e1000_82571.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_82575.c optional em | igb \
|
||||
dev/e1000/e1000_82575.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_ich8lan.c optional em | igb \
|
||||
dev/e1000/e1000_ich8lan.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_i210.c optional em | igb \
|
||||
dev/e1000/e1000_i210.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_api.c optional em | igb \
|
||||
dev/e1000/e1000_api.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_mac.c optional em | igb \
|
||||
dev/e1000/e1000_mac.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_manage.c optional em | igb \
|
||||
dev/e1000/e1000_manage.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_nvm.c optional em | igb \
|
||||
dev/e1000/e1000_nvm.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_phy.c optional em | igb \
|
||||
dev/e1000/e1000_phy.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_vf.c optional em | igb \
|
||||
dev/e1000/e1000_vf.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_mbx.c optional em | igb \
|
||||
dev/e1000/e1000_mbx.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_osdep.c optional em | igb \
|
||||
dev/e1000/e1000_osdep.c optional em \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/et/if_et.c optional et
|
||||
dev/en/if_en_pci.c optional en pci
|
||||
|
@ -38,7 +38,6 @@ LINT: ${NOTES} ../../conf/makeLINT.sed
|
||||
echo "nodevice bxe" >> ${.TARGET}-NOIP
|
||||
echo "nodevice em" >> ${.TARGET}-NOIP
|
||||
echo "nodevice fxp" >> ${.TARGET}-NOIP
|
||||
echo "nodevice igb" >> ${.TARGET}-NOIP
|
||||
echo "nodevice jme" >> ${.TARGET}-NOIP
|
||||
echo "nodevice msk" >> ${.TARGET}-NOIP
|
||||
echo "nodevice mxge" >> ${.TARGET}-NOIP
|
||||
|
720
sys/dev/e1000/em_txrx.c
Normal file
720
sys/dev/e1000/em_txrx.c
Normal file
@ -0,0 +1,720 @@
|
||||
/* $FreeBSD$ */
|
||||
#include "if_em.h"
|
||||
|
||||
#ifdef RSS
|
||||
#include <net/rss_config.h>
|
||||
#include <netinet/in_rss.h>
|
||||
#endif
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
#define DPRINTF device_printf
|
||||
#else
|
||||
#define DPRINTF(...)
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* Local Function prototypes
|
||||
*********************************************************************/
|
||||
static int em_tso_setup(struct adapter *adapter, if_pkt_info_t pi, u32 *txd_upper, u32 *txd_lower);
|
||||
static int em_transmit_checksum_setup(struct adapter *adapter, if_pkt_info_t pi, u32 *txd_upper, u32 *txd_lower);
|
||||
static int em_isc_txd_encap(void *arg, if_pkt_info_t pi);
|
||||
static void em_isc_txd_flush(void *arg, uint16_t txqid, uint32_t pidx);
|
||||
static int em_isc_txd_credits_update(void *arg, uint16_t txqid, uint32_t cidx_init, bool clear);
|
||||
static void em_isc_rxd_refill(void *arg, uint16_t rxqid, uint8_t flid __unused,
|
||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs __unused, uint16_t count, uint16_t buflen __unused);
|
||||
static void em_isc_rxd_flush(void *arg, uint16_t rxqid, uint8_t flid __unused, uint32_t pidx);
|
||||
static int em_isc_rxd_available(void *arg, uint16_t rxqid, uint32_t idx,
|
||||
int budget);
|
||||
static int em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri);
|
||||
|
||||
static void lem_isc_rxd_refill(void *arg, uint16_t rxqid, uint8_t flid __unused,
|
||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs __unused, uint16_t count, uint16_t buflen __unused);
|
||||
|
||||
static int lem_isc_rxd_available(void *arg, uint16_t rxqid, uint32_t idx,
|
||||
int budget);
|
||||
static int lem_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri);
|
||||
|
||||
static void lem_receive_checksum(int status, int errors, if_rxd_info_t ri);
|
||||
static void em_receive_checksum(uint32_t status, if_rxd_info_t ri);
|
||||
extern int em_intr(void *arg);
|
||||
|
||||
struct if_txrx em_txrx = {
|
||||
em_isc_txd_encap,
|
||||
em_isc_txd_flush,
|
||||
em_isc_txd_credits_update,
|
||||
em_isc_rxd_available,
|
||||
em_isc_rxd_pkt_get,
|
||||
em_isc_rxd_refill,
|
||||
em_isc_rxd_flush,
|
||||
em_intr
|
||||
};
|
||||
|
||||
struct if_txrx lem_txrx = {
|
||||
em_isc_txd_encap,
|
||||
em_isc_txd_flush,
|
||||
em_isc_txd_credits_update,
|
||||
lem_isc_rxd_available,
|
||||
lem_isc_rxd_pkt_get,
|
||||
lem_isc_rxd_refill,
|
||||
em_isc_rxd_flush,
|
||||
em_intr
|
||||
};
|
||||
|
||||
extern if_shared_ctx_t em_sctx;
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Setup work for hardware segmentation offload (TSO) on
|
||||
* adapters using advanced tx descriptors
|
||||
*
|
||||
**********************************************************************/
|
||||
static int
|
||||
em_tso_setup(struct adapter *adapter, if_pkt_info_t pi, u32 *txd_upper, u32 *txd_lower)
|
||||
{
|
||||
if_softc_ctx_t scctx = adapter->shared;
|
||||
struct em_tx_queue *que = &adapter->tx_queues[pi->ipi_qsidx];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
struct e1000_context_desc *TXD;
|
||||
struct em_txbuffer *tx_buffer;
|
||||
int cur, hdr_len;
|
||||
|
||||
hdr_len = pi->ipi_ehdrlen + pi->ipi_ip_hlen + pi->ipi_tcp_hlen;
|
||||
*txd_lower = (E1000_TXD_CMD_DEXT | /* Extended descr type */
|
||||
E1000_TXD_DTYP_D | /* Data descr type */
|
||||
E1000_TXD_CMD_TSE); /* Do TSE on this packet */
|
||||
|
||||
/* IP and/or TCP header checksum calculation and insertion. */
|
||||
*txd_upper = (E1000_TXD_POPTS_IXSM | E1000_TXD_POPTS_TXSM) << 8;
|
||||
|
||||
cur = pi->ipi_pidx;
|
||||
TXD = (struct e1000_context_desc *)&txr->tx_base[cur];
|
||||
tx_buffer = &txr->tx_buffers[cur];
|
||||
|
||||
/*
|
||||
* Start offset for header checksum calculation.
|
||||
* End offset for header checksum calculation.
|
||||
* Offset of place put the checksum.
|
||||
*/
|
||||
TXD->lower_setup.ip_fields.ipcss = pi->ipi_ehdrlen;
|
||||
TXD->lower_setup.ip_fields.ipcse =
|
||||
htole16(pi->ipi_ehdrlen + pi->ipi_ip_hlen - 1);
|
||||
TXD->lower_setup.ip_fields.ipcso = pi->ipi_ehdrlen + offsetof(struct ip, ip_sum);
|
||||
|
||||
/*
|
||||
* Start offset for payload checksum calculation.
|
||||
* End offset for payload checksum calculation.
|
||||
* Offset of place to put the checksum.
|
||||
*/
|
||||
TXD->upper_setup.tcp_fields.tucss = pi->ipi_ehdrlen + pi->ipi_ip_hlen;
|
||||
TXD->upper_setup.tcp_fields.tucse = 0;
|
||||
TXD->upper_setup.tcp_fields.tucso =
|
||||
pi->ipi_ehdrlen + pi->ipi_ip_hlen + offsetof(struct tcphdr, th_sum);
|
||||
|
||||
/*
|
||||
* Payload size per packet w/o any headers.
|
||||
* Length of all headers up to payload.
|
||||
*/
|
||||
TXD->tcp_seg_setup.fields.mss = htole16(pi->ipi_tso_segsz);
|
||||
TXD->tcp_seg_setup.fields.hdr_len = hdr_len;
|
||||
|
||||
TXD->cmd_and_length = htole32(adapter->txd_cmd |
|
||||
E1000_TXD_CMD_DEXT | /* Extended descr */
|
||||
E1000_TXD_CMD_TSE | /* TSE context */
|
||||
E1000_TXD_CMD_IP | /* Do IP csum */
|
||||
E1000_TXD_CMD_TCP | /* Do TCP checksum */
|
||||
(pi->ipi_len - hdr_len)); /* Total len */
|
||||
tx_buffer->eop = -1;
|
||||
txr->tx_tso = TRUE;
|
||||
|
||||
if (++cur == scctx->isc_ntxd[0]) {
|
||||
cur = 0;
|
||||
}
|
||||
DPRINTF(iflib_get_dev(adapter->ctx), "%s: pidx: %d cur: %d\n", __FUNCTION__, pi->ipi_pidx, cur);
|
||||
return (cur);
|
||||
}
|
||||
|
||||
#define TSO_WORKAROUND 4
|
||||
#define DONT_FORCE_CTX 1
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* The offload context is protocol specific (TCP/UDP) and thus
|
||||
* only needs to be set when the protocol changes. The occasion
|
||||
* of a context change can be a performance detriment, and
|
||||
* might be better just disabled. The reason arises in the way
|
||||
* in which the controller supports pipelined requests from the
|
||||
* Tx data DMA. Up to four requests can be pipelined, and they may
|
||||
* belong to the same packet or to multiple packets. However all
|
||||
* requests for one packet are issued before a request is issued
|
||||
* for a subsequent packet and if a request for the next packet
|
||||
* requires a context change, that request will be stalled
|
||||
* until the previous request completes. This means setting up
|
||||
* a new context effectively disables pipelined Tx data DMA which
|
||||
* in turn greatly slow down performance to send small sized
|
||||
* frames.
|
||||
**********************************************************************/
|
||||
|
||||
static int
|
||||
em_transmit_checksum_setup(struct adapter *adapter, if_pkt_info_t pi, u32 *txd_upper, u32 *txd_lower)
|
||||
{
|
||||
struct e1000_context_desc *TXD = NULL;
|
||||
if_softc_ctx_t scctx = adapter->shared;
|
||||
struct em_tx_queue *que = &adapter->tx_queues[pi->ipi_qsidx];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
struct em_txbuffer *tx_buffer;
|
||||
int csum_flags = pi->ipi_csum_flags;
|
||||
int cur, hdr_len;
|
||||
u32 cmd;
|
||||
|
||||
cur = pi->ipi_pidx;
|
||||
hdr_len = pi->ipi_ehdrlen + pi->ipi_ip_hlen;
|
||||
cmd = adapter->txd_cmd;
|
||||
|
||||
/*
|
||||
* The 82574L can only remember the *last* context used
|
||||
* regardless of queue that it was use for. We cannot reuse
|
||||
* contexts on this hardware platform and must generate a new
|
||||
* context every time. 82574L hardware spec, section 7.2.6,
|
||||
* second note.
|
||||
*/
|
||||
if (DONT_FORCE_CTX &&
|
||||
adapter->tx_num_queues == 1 &&
|
||||
txr->csum_lhlen == pi->ipi_ehdrlen &&
|
||||
txr->csum_iphlen == pi->ipi_ip_hlen &&
|
||||
txr->csum_flags == csum_flags) {
|
||||
/*
|
||||
* Same csum offload context as the previous packets;
|
||||
* just return.
|
||||
*/
|
||||
*txd_upper = txr->csum_txd_upper;
|
||||
*txd_lower = txr->csum_txd_lower;
|
||||
return (cur);
|
||||
}
|
||||
|
||||
TXD = (struct e1000_context_desc *)&txr->tx_base[cur];
|
||||
if (csum_flags & CSUM_IP) {
|
||||
*txd_upper |= E1000_TXD_POPTS_IXSM << 8;
|
||||
/*
|
||||
* Start offset for header checksum calculation.
|
||||
* End offset for header checksum calculation.
|
||||
* Offset of place to put the checksum.
|
||||
*/
|
||||
TXD->lower_setup.ip_fields.ipcss = pi->ipi_ehdrlen;
|
||||
TXD->lower_setup.ip_fields.ipcse = htole16(hdr_len);
|
||||
TXD->lower_setup.ip_fields.ipcso = pi->ipi_ehdrlen + offsetof(struct ip, ip_sum);
|
||||
cmd |= E1000_TXD_CMD_IP;
|
||||
}
|
||||
|
||||
if (csum_flags & (CSUM_TCP|CSUM_UDP)) {
|
||||
uint8_t tucso;
|
||||
|
||||
*txd_upper |= E1000_TXD_POPTS_TXSM << 8;
|
||||
*txd_lower = E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
|
||||
|
||||
if (csum_flags & CSUM_TCP) {
|
||||
tucso = hdr_len + offsetof(struct tcphdr, th_sum);
|
||||
cmd |= E1000_TXD_CMD_TCP;
|
||||
} else
|
||||
tucso = hdr_len + offsetof(struct udphdr, uh_sum);
|
||||
TXD->upper_setup.tcp_fields.tucss = hdr_len;
|
||||
TXD->upper_setup.tcp_fields.tucse = htole16(0);
|
||||
TXD->upper_setup.tcp_fields.tucso = tucso;
|
||||
}
|
||||
|
||||
txr->csum_lhlen = pi->ipi_ehdrlen;
|
||||
txr->csum_iphlen = pi->ipi_ip_hlen;
|
||||
txr->csum_flags = csum_flags;
|
||||
txr->csum_txd_upper = *txd_upper;
|
||||
txr->csum_txd_lower = *txd_lower;
|
||||
|
||||
TXD->tcp_seg_setup.data = htole32(0);
|
||||
TXD->cmd_and_length =
|
||||
htole32(E1000_TXD_CMD_IFCS | E1000_TXD_CMD_DEXT | cmd);
|
||||
|
||||
tx_buffer = &txr->tx_buffers[cur];
|
||||
tx_buffer->eop = -1;
|
||||
|
||||
if (++cur == scctx->isc_ntxd[0]) {
|
||||
cur = 0;
|
||||
}
|
||||
DPRINTF(iflib_get_dev(adapter->ctx), "checksum_setup csum_flags=%x txd_upper=%x txd_lower=%x hdr_len=%d cmd=%x\n",
|
||||
csum_flags, *txd_upper, *txd_lower, hdr_len, cmd);
|
||||
return (cur);
|
||||
}
|
||||
|
||||
static int
|
||||
em_isc_txd_encap(void *arg, if_pkt_info_t pi)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_tx_queue *que = &sc->tx_queues[pi->ipi_qsidx];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
bus_dma_segment_t *segs = pi->ipi_segs;
|
||||
int nsegs = pi->ipi_nsegs;
|
||||
int csum_flags = pi->ipi_csum_flags;
|
||||
int i, j, first, pidx_last;
|
||||
u32 txd_upper = 0, txd_lower = 0;
|
||||
|
||||
struct em_txbuffer *tx_buffer;
|
||||
struct e1000_tx_desc *ctxd = NULL;
|
||||
bool do_tso, tso_desc;
|
||||
|
||||
i = first = pi->ipi_pidx;
|
||||
do_tso = (csum_flags & CSUM_TSO);
|
||||
tso_desc = FALSE;
|
||||
/*
|
||||
* TSO Hardware workaround, if this packet is not
|
||||
* TSO, and is only a single descriptor long, and
|
||||
* it follows a TSO burst, then we need to add a
|
||||
* sentinel descriptor to prevent premature writeback.
|
||||
*/
|
||||
if ((!do_tso) && (txr->tx_tso == TRUE)) {
|
||||
if (nsegs == 1)
|
||||
tso_desc = TRUE;
|
||||
txr->tx_tso = FALSE;
|
||||
}
|
||||
|
||||
/* Do hardware assists */
|
||||
if (do_tso) {
|
||||
i = em_tso_setup(sc, pi, &txd_upper, &txd_lower);
|
||||
tso_desc = TRUE;
|
||||
} else if (csum_flags & CSUM_OFFLOAD) {
|
||||
i = em_transmit_checksum_setup(sc, pi, &txd_upper, &txd_lower);
|
||||
}
|
||||
|
||||
if (pi->ipi_mflags & M_VLANTAG) {
|
||||
/* Set the vlan id. */
|
||||
txd_upper |= htole16(pi->ipi_vtag) << 16;
|
||||
/* Tell hardware to add tag */
|
||||
txd_lower |= htole32(E1000_TXD_CMD_VLE);
|
||||
}
|
||||
|
||||
DPRINTF(iflib_get_dev(sc->ctx), "encap: set up tx: nsegs=%d first=%d i=%d\n", nsegs, first, i);
|
||||
/* XXX adapter->pcix_82544 -- lem_fill_descriptors */
|
||||
|
||||
/* Set up our transmit descriptors */
|
||||
for (j = 0; j < nsegs; j++) {
|
||||
bus_size_t seg_len;
|
||||
bus_addr_t seg_addr;
|
||||
uint32_t cmd;
|
||||
|
||||
ctxd = &txr->tx_base[i];
|
||||
tx_buffer = &txr->tx_buffers[i];
|
||||
seg_addr = segs[j].ds_addr;
|
||||
seg_len = segs[j].ds_len;
|
||||
cmd = E1000_TXD_CMD_IFCS | sc->txd_cmd;
|
||||
|
||||
/*
|
||||
** TSO Workaround:
|
||||
** If this is the last descriptor, we want to
|
||||
** split it so we have a small final sentinel
|
||||
*/
|
||||
if (tso_desc && (j == (nsegs - 1)) && (seg_len > 8)) {
|
||||
seg_len -= TSO_WORKAROUND;
|
||||
ctxd->buffer_addr = htole64(seg_addr);
|
||||
ctxd->lower.data = htole32(cmd | txd_lower | seg_len);
|
||||
ctxd->upper.data = htole32(txd_upper);
|
||||
|
||||
if (++i == scctx->isc_ntxd[0])
|
||||
i = 0;
|
||||
|
||||
/* Now make the sentinel */
|
||||
ctxd = &txr->tx_base[i];
|
||||
tx_buffer = &txr->tx_buffers[i];
|
||||
ctxd->buffer_addr = htole64(seg_addr + seg_len);
|
||||
ctxd->lower.data = htole32(cmd | txd_lower | TSO_WORKAROUND);
|
||||
ctxd->upper.data = htole32(txd_upper);
|
||||
pidx_last = i;
|
||||
if (++i == scctx->isc_ntxd[0])
|
||||
i = 0;
|
||||
DPRINTF(iflib_get_dev(sc->ctx), "TSO path pidx_last=%d i=%d ntxd[0]=%d\n", pidx_last, i, scctx->isc_ntxd[0]);
|
||||
} else {
|
||||
ctxd->buffer_addr = htole64(seg_addr);
|
||||
ctxd->lower.data = htole32(cmd | txd_lower | seg_len);
|
||||
ctxd->upper.data = htole32(txd_upper);
|
||||
pidx_last = i;
|
||||
if (++i == scctx->isc_ntxd[0])
|
||||
i = 0;
|
||||
DPRINTF(iflib_get_dev(sc->ctx), "pidx_last=%d i=%d ntxd[0]=%d\n", pidx_last, i, scctx->isc_ntxd[0]);
|
||||
}
|
||||
tx_buffer->eop = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Last Descriptor of Packet
|
||||
* needs End Of Packet (EOP)
|
||||
* and Report Status (RS)
|
||||
*/
|
||||
ctxd->lower.data |=
|
||||
htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS);
|
||||
|
||||
tx_buffer = &txr->tx_buffers[first];
|
||||
tx_buffer->eop = pidx_last;
|
||||
DPRINTF(iflib_get_dev(sc->ctx), "tx_buffers[%d]->eop = %d ipi_new_pidx=%d\n", first, pidx_last, i);
|
||||
pi->ipi_new_pidx = i;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
em_isc_txd_flush(void *arg, uint16_t txqid, uint32_t pidx)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
struct em_tx_queue *que = &adapter->tx_queues[txqid];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), pidx);
|
||||
}
|
||||
|
||||
static int
|
||||
em_isc_txd_credits_update(void *arg, uint16_t txqid, uint32_t cidx_init, bool clear)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
if_softc_ctx_t scctx = adapter->shared;
|
||||
struct em_tx_queue *que = &adapter->tx_queues[txqid];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
|
||||
u32 cidx, processed = 0;
|
||||
int last, done;
|
||||
struct em_txbuffer *buf;
|
||||
struct e1000_tx_desc *tx_desc, *eop_desc;
|
||||
|
||||
cidx = cidx_init;
|
||||
buf = &txr->tx_buffers[cidx];
|
||||
tx_desc = &txr->tx_base[cidx];
|
||||
last = buf->eop;
|
||||
eop_desc = &txr->tx_base[last];
|
||||
|
||||
DPRINTF(iflib_get_dev(adapter->ctx), "credits_update: cidx_init=%d clear=%d last=%d\n",
|
||||
cidx_init, clear, last);
|
||||
/*
|
||||
* What this does is get the index of the
|
||||
* first descriptor AFTER the EOP of the
|
||||
* first packet, that way we can do the
|
||||
* simple comparison on the inner while loop.
|
||||
*/
|
||||
if (++last == scctx->isc_ntxd[0])
|
||||
last = 0;
|
||||
done = last;
|
||||
|
||||
|
||||
while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) {
|
||||
/* We clean the range of the packet */
|
||||
while (cidx != done) {
|
||||
if (clear) {
|
||||
tx_desc->upper.data = 0;
|
||||
tx_desc->lower.data = 0;
|
||||
tx_desc->buffer_addr = 0;
|
||||
buf->eop = -1;
|
||||
}
|
||||
tx_desc++;
|
||||
buf++;
|
||||
processed++;
|
||||
|
||||
/* wrap the ring ? */
|
||||
if (++cidx == scctx->isc_ntxd[0]) {
|
||||
cidx = 0;
|
||||
}
|
||||
buf = &txr->tx_buffers[cidx];
|
||||
tx_desc = &txr->tx_base[cidx];
|
||||
}
|
||||
/* See if we can continue to the next packet */
|
||||
last = buf->eop;
|
||||
if (last == -1)
|
||||
break;
|
||||
eop_desc = &txr->tx_base[last];
|
||||
/* Get new done point */
|
||||
if (++last == scctx->isc_ntxd[0])
|
||||
last = 0;
|
||||
done = last;
|
||||
}
|
||||
|
||||
DPRINTF(iflib_get_dev(adapter->ctx), "Processed %d credits update\n", processed);
|
||||
return(processed);
|
||||
}
|
||||
|
||||
static void
|
||||
lem_isc_rxd_refill(void *arg, uint16_t rxqid, uint8_t flid __unused,
|
||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs __unused, uint16_t count, uint16_t buflen __unused)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
struct e1000_rx_desc *rxd;
|
||||
int i;
|
||||
uint32_t next_pidx;
|
||||
|
||||
for (i = 0, next_pidx = pidx; i < count; i++) {
|
||||
rxd = (struct e1000_rx_desc *)&rxr->rx_base[next_pidx];
|
||||
rxd->buffer_addr = htole64(paddrs[i]);
|
||||
/* status bits must be cleared */
|
||||
rxd->status = 0;
|
||||
|
||||
if (++next_pidx == scctx->isc_nrxd[0])
|
||||
next_pidx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
em_isc_rxd_refill(void *arg, uint16_t rxqid, uint8_t flid __unused,
|
||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs __unused, uint16_t count, uint16_t buflen __unused)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
union e1000_rx_desc_extended *rxd;
|
||||
int i;
|
||||
uint32_t next_pidx;
|
||||
|
||||
for (i = 0, next_pidx = pidx; i < count; i++) {
|
||||
rxd = &rxr->rx_base[next_pidx];
|
||||
rxd->read.buffer_addr = htole64(paddrs[i]);
|
||||
/* DD bits must be cleared */
|
||||
rxd->wb.upper.status_error = 0;
|
||||
|
||||
if (++next_pidx == scctx->isc_nrxd[0])
|
||||
next_pidx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
em_isc_rxd_flush(void *arg, uint16_t rxqid, uint8_t flid __unused, uint32_t pidx)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
|
||||
E1000_WRITE_REG(&sc->hw, E1000_RDT(rxr->me), pidx);
|
||||
}
|
||||
|
||||
static int
|
||||
lem_isc_rxd_available(void *arg, uint16_t rxqid, uint32_t idx, int budget)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
struct e1000_rx_desc *rxd;
|
||||
u32 staterr = 0;
|
||||
int cnt, i;
|
||||
|
||||
for (cnt = 0, i = idx; cnt < scctx->isc_nrxd[0] && cnt <= budget;) {
|
||||
rxd = (struct e1000_rx_desc *)&rxr->rx_base[i];
|
||||
staterr = rxd->status;
|
||||
|
||||
if ((staterr & E1000_RXD_STAT_DD) == 0)
|
||||
break;
|
||||
|
||||
if (++i == scctx->isc_nrxd[0])
|
||||
i = 0;
|
||||
|
||||
if (staterr & E1000_RXD_STAT_EOP)
|
||||
cnt++;
|
||||
}
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
static int
|
||||
em_isc_rxd_available(void *arg, uint16_t rxqid, uint32_t idx, int budget)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
union e1000_rx_desc_extended *rxd;
|
||||
u32 staterr = 0;
|
||||
int cnt, i;
|
||||
|
||||
for (cnt = 0, i = idx; cnt < scctx->isc_nrxd[0] && cnt <= budget;) {
|
||||
rxd = &rxr->rx_base[i];
|
||||
staterr = le32toh(rxd->wb.upper.status_error);
|
||||
|
||||
if ((staterr & E1000_RXD_STAT_DD) == 0)
|
||||
break;
|
||||
|
||||
if (++i == scctx->isc_nrxd[0]) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (staterr & E1000_RXD_STAT_EOP)
|
||||
cnt++;
|
||||
|
||||
}
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
static int
|
||||
lem_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
if_softc_ctx_t scctx = adapter->shared;
|
||||
struct em_rx_queue *que = &adapter->rx_queues[ri->iri_qsidx];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
struct e1000_rx_desc *rxd;
|
||||
u16 len;
|
||||
u32 status, errors;
|
||||
bool eop;
|
||||
int i, cidx;
|
||||
|
||||
status = errors = i = 0;
|
||||
cidx = ri->iri_cidx;
|
||||
|
||||
do {
|
||||
rxd = (struct e1000_rx_desc *)&rxr->rx_base[cidx];
|
||||
status = rxd->status;
|
||||
errors = rxd->errors;
|
||||
|
||||
/* Error Checking then decrement count */
|
||||
MPASS ((status & E1000_RXD_STAT_DD) != 0);
|
||||
|
||||
len = le16toh(rxd->length);
|
||||
ri->iri_len += len;
|
||||
|
||||
eop = (status & E1000_RXD_STAT_EOP) != 0;
|
||||
|
||||
/* Make sure bad packets are discarded */
|
||||
if (errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
|
||||
adapter->dropped_pkts++;
|
||||
/* XXX fixup if common */
|
||||
return (EBADMSG);
|
||||
}
|
||||
|
||||
ri->iri_frags[i].irf_flid = 0;
|
||||
ri->iri_frags[i].irf_idx = cidx;
|
||||
ri->iri_frags[i].irf_len = len;
|
||||
/* Zero out the receive descriptors status. */
|
||||
rxd->status = 0;
|
||||
|
||||
if (++cidx == scctx->isc_nrxd[0])
|
||||
cidx = 0;
|
||||
i++;
|
||||
} while (!eop);
|
||||
|
||||
/* XXX add a faster way to look this up */
|
||||
if (adapter->hw.mac.type >= e1000_82543 && !(status & E1000_RXD_STAT_IXSM))
|
||||
lem_receive_checksum(status, errors, ri);
|
||||
|
||||
if (status & E1000_RXD_STAT_VP) {
|
||||
ri->iri_vtag = le16toh(rxd->special);
|
||||
ri->iri_flags |= M_VLANTAG;
|
||||
}
|
||||
|
||||
ri->iri_nfrags = i;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
em_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
if_softc_ctx_t scctx = adapter->shared;
|
||||
struct em_rx_queue *que = &adapter->rx_queues[ri->iri_qsidx];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
union e1000_rx_desc_extended *rxd;
|
||||
|
||||
u16 len;
|
||||
u32 staterr = 0;
|
||||
bool eop;
|
||||
int i, cidx, vtag;
|
||||
|
||||
i = vtag = 0;
|
||||
cidx = ri->iri_cidx;
|
||||
|
||||
do {
|
||||
rxd = &rxr->rx_base[cidx];
|
||||
staterr = le32toh(rxd->wb.upper.status_error);
|
||||
|
||||
/* Error Checking then decrement count */
|
||||
MPASS ((staterr & E1000_RXD_STAT_DD) != 0);
|
||||
|
||||
len = le16toh(rxd->wb.upper.length);
|
||||
ri->iri_len += len;
|
||||
|
||||
eop = (staterr & E1000_RXD_STAT_EOP) != 0;
|
||||
|
||||
/* Make sure bad packets are discarded */
|
||||
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
|
||||
adapter->dropped_pkts++;
|
||||
return EBADMSG;
|
||||
}
|
||||
|
||||
ri->iri_frags[i].irf_flid = 0;
|
||||
ri->iri_frags[i].irf_idx = cidx;
|
||||
ri->iri_frags[i].irf_len = len;
|
||||
/* Zero out the receive descriptors status. */
|
||||
rxd->wb.upper.status_error &= htole32(~0xFF);
|
||||
|
||||
if (++cidx == scctx->isc_nrxd[0])
|
||||
cidx = 0;
|
||||
i++;
|
||||
} while (!eop);
|
||||
|
||||
/* XXX add a faster way to look this up */
|
||||
if (adapter->hw.mac.type >= e1000_82543)
|
||||
em_receive_checksum(staterr, ri);
|
||||
|
||||
if (staterr & E1000_RXD_STAT_VP) {
|
||||
vtag = le16toh(rxd->wb.upper.vlan);
|
||||
}
|
||||
|
||||
ri->iri_vtag = vtag;
|
||||
ri->iri_nfrags = i;
|
||||
if (vtag)
|
||||
ri->iri_flags |= M_VLANTAG;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Verify that the hardware indicated that the checksum is valid.
|
||||
* Inform the stack about the status of checksum so that stack
|
||||
* doesn't spend time verifying the checksum.
|
||||
*
|
||||
*********************************************************************/
|
||||
static void
|
||||
lem_receive_checksum(int status, int errors, if_rxd_info_t ri)
|
||||
{
|
||||
/* Did it pass? */
|
||||
if (status & E1000_RXD_STAT_IPCS && !(errors & E1000_RXD_ERR_IPE))
|
||||
ri->iri_csum_flags = (CSUM_IP_CHECKED|CSUM_IP_VALID);
|
||||
|
||||
if (status & E1000_RXD_STAT_TCPCS) {
|
||||
/* Did it pass? */
|
||||
if (!(errors & E1000_RXD_ERR_TCPE)) {
|
||||
ri->iri_csum_flags |=
|
||||
(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
ri->iri_csum_data = htons(0xffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
em_receive_checksum(uint32_t status, if_rxd_info_t ri)
|
||||
{
|
||||
ri->iri_csum_flags = 0;
|
||||
|
||||
/* Ignore Checksum bit is set */
|
||||
if (status & E1000_RXD_STAT_IXSM)
|
||||
return;
|
||||
|
||||
/* If the IP checksum exists and there is no IP Checksum error */
|
||||
if ((status & (E1000_RXD_STAT_IPCS | E1000_RXDEXT_STATERR_IPE)) ==
|
||||
E1000_RXD_STAT_IPCS) {
|
||||
ri->iri_csum_flags = (CSUM_IP_CHECKED | CSUM_IP_VALID);
|
||||
}
|
||||
|
||||
/* TCP or UDP checksum */
|
||||
if ((status & (E1000_RXD_STAT_TCPCS | E1000_RXDEXT_STATERR_TCPE)) ==
|
||||
E1000_RXD_STAT_TCPCS) {
|
||||
ri->iri_csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
ri->iri_csum_data = htons(0xffff);
|
||||
}
|
||||
if (status & E1000_RXD_STAT_UDPCS) {
|
||||
ri->iri_csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
ri->iri_csum_data = htons(0xffff);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,36 +1,67 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2015, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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$*/
|
||||
#include "opt_em.h"
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#ifdef DDB
|
||||
#include <sys/types.h>
|
||||
#include <ddb/ddb.h>
|
||||
#endif
|
||||
#if __FreeBSD_version >= 800000
|
||||
#include <sys/buf_ring.h>
|
||||
#endif
|
||||
#include <sys/bus.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/iflib.h>
|
||||
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_vlan_var.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include <machine/in_cksum.h>
|
||||
#include <dev/led/led.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include "e1000_api.h"
|
||||
#include "e1000_82571.h"
|
||||
#include "ifdi_if.h"
|
||||
|
||||
|
||||
#ifndef _EM_H_DEFINED_
|
||||
@ -51,13 +82,10 @@
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_TXD 80
|
||||
#define EM_MIN_TXD 128
|
||||
#define EM_MAX_TXD 4096
|
||||
#ifdef EM_MULTIQUEUE
|
||||
#define EM_DEFAULT_TXD 4096
|
||||
#else
|
||||
#define EM_DEFAULT_TXD 1024
|
||||
#endif
|
||||
#define EM_DEFAULT_TXD 1024
|
||||
#define EM_DEFAULT_MULTI_TXD 4096
|
||||
|
||||
/*
|
||||
* EM_RXD - Maximum number of receive Descriptors
|
||||
@ -72,13 +100,10 @@
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_RXD 80
|
||||
#define EM_MIN_RXD 128
|
||||
#define EM_MAX_RXD 4096
|
||||
#ifdef EM_MULTIQUEUE
|
||||
#define EM_DEFAULT_RXD 4096
|
||||
#else
|
||||
#define EM_DEFAULT_RXD 1024
|
||||
#endif
|
||||
#define EM_DEFAULT_RXD 1024
|
||||
#define EM_DEFAULT_MULTI_RXD 4096
|
||||
|
||||
/*
|
||||
* EM_TIDV - Transmit Interrupt Delay Value
|
||||
@ -148,17 +173,6 @@
|
||||
#define EM_RADV 64
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This parameter controls the max duration of transmit watchdog.
|
||||
*/
|
||||
#define EM_WATCHDOG (10 * hz)
|
||||
|
||||
/*
|
||||
* This parameter controls when the driver calls the routine to reclaim
|
||||
* transmit descriptors.
|
||||
*/
|
||||
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
|
||||
|
||||
/*
|
||||
* This parameter controls whether or not autonegotation is enabled.
|
||||
* 0 - Disable autonegotiation
|
||||
@ -221,6 +235,18 @@
|
||||
#define PCICFG_DESC_RING_STATUS 0xe4
|
||||
#define FLUSH_DESC_REQUIRED 0x100
|
||||
|
||||
|
||||
#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : \
|
||||
((hw->mac.type <= e1000_82576) ? 16 : 8))
|
||||
#define IGB_RX_HTHRESH 8
|
||||
#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
|
||||
(adapter->intr_type == IFLIB_INTR_MSIX)) ? 1 : 4)
|
||||
|
||||
#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
|
||||
#define IGB_TX_HTHRESH 1
|
||||
#define IGB_TX_WTHRESH ((hw->mac.type != e1000_82575 && \
|
||||
(adapter->intr_type == IFLIB_INTR_MSIX) ? 1 : 16)
|
||||
|
||||
/*
|
||||
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
|
||||
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
|
||||
@ -242,6 +268,7 @@
|
||||
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
|
||||
#define EM_BAR_TYPE_MASK 0x00000001
|
||||
#define EM_BAR_TYPE_MMEM 0x00000000
|
||||
#define EM_BAR_TYPE_IO 0x00000001
|
||||
#define EM_BAR_TYPE_FLASH 0x0014
|
||||
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
|
||||
#define EM_BAR_MEM_TYPE_MASK 0x00000006
|
||||
@ -279,6 +306,9 @@
|
||||
#define ETH_ADDR_LEN 6
|
||||
#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
|
||||
|
||||
#define IGB_PKTTYPE_MASK 0x0000FFF0
|
||||
#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coalesce Flush */
|
||||
|
||||
/*
|
||||
* 82574 has a nonstandard address for EIAC
|
||||
* and since its only used in MSIX, and in
|
||||
@ -295,19 +325,6 @@
|
||||
#define EM_NVM_MSIX_N_MASK (0x7 << EM_NVM_MSIX_N_SHIFT)
|
||||
#define EM_NVM_MSIX_N_SHIFT 7
|
||||
|
||||
/*
|
||||
* Bus dma allocation structure used by
|
||||
* e1000_dma_malloc and e1000_dma_free.
|
||||
*/
|
||||
struct em_dma_alloc {
|
||||
bus_addr_t dma_paddr;
|
||||
caddr_t dma_vaddr;
|
||||
bus_dma_tag_t dma_tag;
|
||||
bus_dmamap_t dma_map;
|
||||
bus_dma_segment_t dma_seg;
|
||||
int dma_nseg;
|
||||
};
|
||||
|
||||
struct adapter;
|
||||
|
||||
struct em_int_delay_info {
|
||||
@ -321,35 +338,31 @@ struct em_int_delay_info {
|
||||
*/
|
||||
struct tx_ring {
|
||||
struct adapter *adapter;
|
||||
struct mtx tx_mtx;
|
||||
char mtx_name[16];
|
||||
struct em_tx_queue *que;
|
||||
u32 me;
|
||||
u32 msix;
|
||||
u32 ims;
|
||||
int busy;
|
||||
struct em_dma_alloc txdma;
|
||||
struct e1000_tx_desc *tx_base;
|
||||
struct task tx_task;
|
||||
struct taskqueue *tq;
|
||||
u32 next_avail_desc;
|
||||
u32 next_to_clean;
|
||||
uint64_t tx_paddr;
|
||||
struct em_txbuffer *tx_buffers;
|
||||
volatile u16 tx_avail;
|
||||
u32 tx_tso; /* last tx was tso */
|
||||
u16 last_hw_offload;
|
||||
u8 last_hw_ipcso;
|
||||
u8 last_hw_ipcss;
|
||||
u8 last_hw_tucso;
|
||||
u8 last_hw_tucss;
|
||||
#if __FreeBSD_version >= 800000
|
||||
struct buf_ring *br;
|
||||
#endif
|
||||
|
||||
/* Interrupt resources */
|
||||
bus_dma_tag_t txtag;
|
||||
void *tag;
|
||||
struct resource *res;
|
||||
unsigned long tx_irq;
|
||||
unsigned long no_desc_avail;
|
||||
|
||||
/* Saved csum offloading context information */
|
||||
int csum_flags;
|
||||
int csum_lhlen;
|
||||
int csum_iphlen;
|
||||
|
||||
int csum_thlen;
|
||||
int csum_mss;
|
||||
int csum_pktlen;
|
||||
|
||||
uint32_t csum_txd_upper;
|
||||
uint32_t csum_txd_lower; /* last field */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -357,26 +370,15 @@ struct tx_ring {
|
||||
*/
|
||||
struct rx_ring {
|
||||
struct adapter *adapter;
|
||||
struct em_rx_queue *que;
|
||||
u32 me;
|
||||
u32 msix;
|
||||
u32 ims;
|
||||
struct mtx rx_mtx;
|
||||
char mtx_name[16];
|
||||
u32 payload;
|
||||
struct task rx_task;
|
||||
struct taskqueue *tq;
|
||||
union e1000_rx_desc_extended *rx_base;
|
||||
struct em_dma_alloc rxdma;
|
||||
u32 next_to_refresh;
|
||||
u32 next_to_check;
|
||||
struct em_rxbuffer *rx_buffers;
|
||||
struct mbuf *fmp;
|
||||
struct mbuf *lmp;
|
||||
uint64_t rx_paddr;
|
||||
|
||||
/* Interrupt resources */
|
||||
void *tag;
|
||||
struct resource *res;
|
||||
bus_dma_tag_t rxtag;
|
||||
bool discard;
|
||||
|
||||
/* Soft stats */
|
||||
@ -386,62 +388,68 @@ struct rx_ring {
|
||||
unsigned long rx_bytes;
|
||||
};
|
||||
|
||||
struct em_tx_queue {
|
||||
struct adapter *adapter;
|
||||
u32 msix;
|
||||
u32 eims; /* This queue's EIMS bit */
|
||||
u32 me;
|
||||
struct tx_ring txr;
|
||||
};
|
||||
|
||||
struct em_rx_queue {
|
||||
struct adapter *adapter;
|
||||
u32 me;
|
||||
u32 msix;
|
||||
u32 eims;
|
||||
struct rx_ring rxr;
|
||||
u64 irqs;
|
||||
struct if_irq que_irq;
|
||||
};
|
||||
|
||||
/* Our adapter structure */
|
||||
struct adapter {
|
||||
if_t ifp;
|
||||
struct ifnet *ifp;
|
||||
struct e1000_hw hw;
|
||||
|
||||
if_softc_ctx_t shared;
|
||||
if_ctx_t ctx;
|
||||
#define tx_num_queues shared->isc_ntxqsets
|
||||
#define rx_num_queues shared->isc_nrxqsets
|
||||
#define intr_type shared->isc_intr
|
||||
/* FreeBSD operating-system-specific structures. */
|
||||
struct e1000_osdep osdep;
|
||||
device_t dev;
|
||||
struct device *dev;
|
||||
struct cdev *led_dev;
|
||||
|
||||
struct em_tx_queue *tx_queues;
|
||||
struct em_rx_queue *rx_queues;
|
||||
struct if_irq irq;
|
||||
|
||||
struct resource *memory;
|
||||
struct resource *flash;
|
||||
struct resource *msix_mem;
|
||||
struct resource *ioport;
|
||||
int io_rid;
|
||||
|
||||
struct resource *res;
|
||||
void *tag;
|
||||
u32 linkvec;
|
||||
u32 ivars;
|
||||
|
||||
struct ifmedia media;
|
||||
struct callout timer;
|
||||
struct ifmedia *media;
|
||||
int msix;
|
||||
int if_flags;
|
||||
int max_frame_size;
|
||||
int min_frame_size;
|
||||
struct mtx core_mtx;
|
||||
int em_insert_vlan_header;
|
||||
u32 ims;
|
||||
bool in_detach;
|
||||
|
||||
/* Task for FAST handling */
|
||||
struct task link_task;
|
||||
struct task que_task;
|
||||
struct taskqueue *tq; /* private task queue */
|
||||
struct grouptask link_task;
|
||||
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
|
||||
u16 num_vlans;
|
||||
u8 num_queues;
|
||||
|
||||
/*
|
||||
* Transmit rings:
|
||||
* Allocated at run time, an array of rings.
|
||||
*/
|
||||
struct tx_ring *tx_rings;
|
||||
int num_tx_desc;
|
||||
u16 num_vlans;
|
||||
u32 txd_cmd;
|
||||
|
||||
/*
|
||||
* Receive rings:
|
||||
* Allocated at run time, an array of rings.
|
||||
*/
|
||||
struct rx_ring *rx_rings;
|
||||
int num_rx_desc;
|
||||
u32 tx_process_limit;
|
||||
u32 rx_process_limit;
|
||||
u32 rx_mbuf_sz;
|
||||
|
||||
@ -467,7 +475,12 @@ struct adapter {
|
||||
u16 link_speed;
|
||||
u16 link_duplex;
|
||||
u32 smartspeed;
|
||||
u32 dmac;
|
||||
int link_mask;
|
||||
|
||||
u64 que_mask;
|
||||
|
||||
|
||||
struct em_int_delay_info tx_int_delay;
|
||||
struct em_int_delay_info tx_abs_int_delay;
|
||||
struct em_int_delay_info rx_int_delay;
|
||||
@ -502,33 +515,9 @@ typedef struct _em_vendor_info_t {
|
||||
} em_vendor_info_t;
|
||||
|
||||
struct em_txbuffer {
|
||||
int next_eop; /* Index of the desc to watch */
|
||||
struct mbuf *m_head;
|
||||
bus_dmamap_t map; /* bus_dma map for packet */
|
||||
int eop;
|
||||
};
|
||||
|
||||
struct em_rxbuffer {
|
||||
int next_eop; /* Index of the desc to watch */
|
||||
struct mbuf *m_head;
|
||||
bus_dmamap_t map; /* bus_dma map for packet */
|
||||
bus_addr_t paddr;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Find the number of unrefreshed RX descriptors
|
||||
*/
|
||||
static inline u16
|
||||
e1000_rx_unrefreshed(struct rx_ring *rxr)
|
||||
{
|
||||
struct adapter *adapter = rxr->adapter;
|
||||
|
||||
if (rxr->next_to_check > rxr->next_to_refresh)
|
||||
return (rxr->next_to_check - rxr->next_to_refresh - 1);
|
||||
else
|
||||
return ((adapter->num_rx_desc + rxr->next_to_check) -
|
||||
rxr->next_to_refresh - 1);
|
||||
}
|
||||
|
||||
#define EM_CORE_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,634 +0,0 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2015, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _IF_IGB_H_
|
||||
#define _IF_IGB_H_
|
||||
|
||||
#ifdef ALTQ
|
||||
#define IGB_LEGACY_TX
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#ifndef IGB_LEGACY_TX
|
||||
#include <sys/buf_ring.h>
|
||||
#endif
|
||||
#include <sys/bus.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/smp.h>
|
||||
#include <machine/smp.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#ifdef RSS
|
||||
#include <net/rss_config.h>
|
||||
#include <netinet/in_rss.h>
|
||||
#endif
|
||||
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_vlan_var.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_lro.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include <machine/in_cksum.h>
|
||||
#include <dev/led/led.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include "e1000_api.h"
|
||||
#include "e1000_82575.h"
|
||||
|
||||
/* Tunables */
|
||||
/*
|
||||
* IGB_TXD: Maximum number of Transmit Descriptors
|
||||
*
|
||||
* This value is the number of transmit descriptors allocated by the driver.
|
||||
* Increasing this value allows the driver to queue more transmits. Each
|
||||
* descriptor is 16 bytes.
|
||||
* Since TDLEN should be multiple of 128bytes, the number of transmit
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define IGB_MIN_TXD 256
|
||||
#define IGB_DEFAULT_TXD 1024
|
||||
#define IGB_MAX_TXD 4096
|
||||
|
||||
/*
|
||||
* IGB_RXD: Maximum number of Receive Descriptors
|
||||
*
|
||||
* This value is the number of receive descriptors allocated by the driver.
|
||||
* Increasing this value allows the driver to buffer more incoming packets.
|
||||
* Each descriptor is 16 bytes. A receive buffer is also allocated for each
|
||||
* descriptor. The maximum MTU size is 16110.
|
||||
* Since TDLEN should be multiple of 128bytes, the number of transmit
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define IGB_MIN_RXD 256
|
||||
#define IGB_DEFAULT_RXD 1024
|
||||
#define IGB_MAX_RXD 4096
|
||||
|
||||
/*
|
||||
* IGB_TIDV - Transmit Interrupt Delay Value
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value delays the generation of transmit interrupts in units of
|
||||
* 1.024 microseconds. Transmit interrupt reduction can improve CPU
|
||||
* efficiency if properly tuned for specific network traffic. If the
|
||||
* system is reporting dropped transmits, this value may be set too high
|
||||
* causing the driver to run out of available transmit descriptors.
|
||||
*/
|
||||
#define IGB_TIDV 64
|
||||
|
||||
/*
|
||||
* IGB_TADV - Transmit Absolute Interrupt Delay Value
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value, in units of 1.024 microseconds, limits the delay in which a
|
||||
* transmit interrupt is generated. Useful only if IGB_TIDV is non-zero,
|
||||
* this value ensures that an interrupt is generated after the initial
|
||||
* packet is sent on the wire within the set amount of time. Proper tuning,
|
||||
* along with IGB_TIDV, may improve traffic throughput in specific
|
||||
* network conditions.
|
||||
*/
|
||||
#define IGB_TADV 64
|
||||
|
||||
/*
|
||||
* IGB_RDTR - Receive Interrupt Delay Timer (Packet Timer)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 0
|
||||
* This value delays the generation of receive interrupts in units of 1.024
|
||||
* microseconds. Receive interrupt reduction can improve CPU efficiency if
|
||||
* properly tuned for specific network traffic. Increasing this value adds
|
||||
* extra latency to frame reception and can end up decreasing the throughput
|
||||
* of TCP traffic. If the system is reporting dropped receives, this value
|
||||
* may be set too high, causing the driver to run out of available receive
|
||||
* descriptors.
|
||||
*
|
||||
* CAUTION: When setting IGB_RDTR to a value other than 0, adapters
|
||||
* may hang (stop transmitting) under certain network conditions.
|
||||
* If this occurs a WATCHDOG message is logged in the system
|
||||
* event log. In addition, the controller is automatically reset,
|
||||
* restoring the network connection. To eliminate the potential
|
||||
* for the hang ensure that IGB_RDTR is set to 0.
|
||||
*/
|
||||
#define IGB_RDTR 0
|
||||
|
||||
/*
|
||||
* Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value, in units of 1.024 microseconds, limits the delay in which a
|
||||
* receive interrupt is generated. Useful only if IGB_RDTR is non-zero,
|
||||
* this value ensures that an interrupt is generated after the initial
|
||||
* packet is received within the set amount of time. Proper tuning,
|
||||
* along with IGB_RDTR, may improve traffic throughput in specific network
|
||||
* conditions.
|
||||
*/
|
||||
#define IGB_RADV 64
|
||||
|
||||
/*
|
||||
* This parameter controls the duration of transmit watchdog timer.
|
||||
*/
|
||||
#define IGB_WATCHDOG (10 * hz)
|
||||
|
||||
/*
|
||||
* This parameter controls when the driver calls the routine to reclaim
|
||||
* transmit descriptors. Cleaning earlier seems a win.
|
||||
*/
|
||||
#define IGB_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 2)
|
||||
|
||||
/*
|
||||
* This parameter controls whether or not autonegotation is enabled.
|
||||
* 0 - Disable autonegotiation
|
||||
* 1 - Enable autonegotiation
|
||||
*/
|
||||
#define DO_AUTO_NEG 1
|
||||
|
||||
/*
|
||||
* This parameter control whether or not the driver will wait for
|
||||
* autonegotiation to complete.
|
||||
* 1 - Wait for autonegotiation to complete
|
||||
* 0 - Don't wait for autonegotiation to complete
|
||||
*/
|
||||
#define WAIT_FOR_AUTO_NEG_DEFAULT 0
|
||||
|
||||
/* Tunables -- End */
|
||||
|
||||
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
|
||||
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
|
||||
ADVERTISE_1000_FULL)
|
||||
|
||||
#define AUTO_ALL_MODES 0
|
||||
|
||||
/* PHY master/slave setting */
|
||||
#define IGB_MASTER_SLAVE e1000_ms_hw_default
|
||||
|
||||
/* Support AutoMediaDetect for Marvell M88 PHY in i354 */
|
||||
#define IGB_MEDIA_RESET (1 << 0)
|
||||
|
||||
/*
|
||||
* Micellaneous constants
|
||||
*/
|
||||
#define IGB_INTEL_VENDOR_ID 0x8086
|
||||
|
||||
#define IGB_JUMBO_PBA 0x00000028
|
||||
#define IGB_DEFAULT_PBA 0x00000030
|
||||
#define IGB_SMARTSPEED_DOWNSHIFT 3
|
||||
#define IGB_SMARTSPEED_MAX 15
|
||||
#define IGB_MAX_LOOP 10
|
||||
|
||||
#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : \
|
||||
((hw->mac.type <= e1000_82576) ? 16 : 8))
|
||||
#define IGB_RX_HTHRESH 8
|
||||
#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
|
||||
adapter->msix_mem) ? 1 : 4)
|
||||
|
||||
#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
|
||||
#define IGB_TX_HTHRESH 1
|
||||
#define IGB_TX_WTHRESH ((hw->mac.type != e1000_82575 && \
|
||||
adapter->msix_mem) ? 1 : 16)
|
||||
|
||||
#define MAX_NUM_MULTICAST_ADDRESSES 128
|
||||
#define PCI_ANY_ID (~0U)
|
||||
#define ETHER_ALIGN 2
|
||||
#define IGB_TX_BUFFER_SIZE ((uint32_t) 1514)
|
||||
#define IGB_FC_PAUSE_TIME 0x0680
|
||||
#define IGB_EEPROM_APME 0x400;
|
||||
/* Queue minimum free for use */
|
||||
#define IGB_QUEUE_THRESHOLD (adapter->num_tx_desc / 8)
|
||||
|
||||
/*
|
||||
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
|
||||
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
|
||||
* also optimize cache line size effect. H/W supports up to cache line size 128.
|
||||
*/
|
||||
#define IGB_DBA_ALIGN 128
|
||||
|
||||
#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
|
||||
|
||||
/* PCI Config defines */
|
||||
#define IGB_MSIX_BAR 3
|
||||
|
||||
/* Defines for printing debug information */
|
||||
#define DEBUG_INIT 0
|
||||
#define DEBUG_IOCTL 0
|
||||
#define DEBUG_HW 0
|
||||
|
||||
#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
|
||||
#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
|
||||
#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
|
||||
#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
|
||||
#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
|
||||
#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
|
||||
#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
|
||||
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
|
||||
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
|
||||
|
||||
#define IGB_MAX_SCATTER 40
|
||||
#define IGB_VFTA_SIZE 128
|
||||
#define IGB_BR_SIZE 4096 /* ring buf size */
|
||||
#define IGB_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
|
||||
#define IGB_TSO_SEG_SIZE 4096 /* Max dma segment size */
|
||||
#define IGB_TXPBSIZE 20408
|
||||
#define IGB_HDR_BUF 128
|
||||
#define IGB_PKTTYPE_MASK 0x0000FFF0
|
||||
#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coalesce Flush */
|
||||
#define ETH_ZLEN 60
|
||||
#define ETH_ADDR_LEN 6
|
||||
|
||||
/* Offload bits in mbuf flag */
|
||||
#if __FreeBSD_version >= 1000000
|
||||
#define CSUM_OFFLOAD_IPV4 (CSUM_IP|CSUM_IP_TCP|CSUM_IP_UDP|CSUM_IP_SCTP)
|
||||
#define CSUM_OFFLOAD_IPV6 (CSUM_IP6_TCP|CSUM_IP6_UDP|CSUM_IP6_SCTP)
|
||||
#define CSUM_OFFLOAD (CSUM_OFFLOAD_IPV4|CSUM_OFFLOAD_IPV6)
|
||||
#elif __FreeBSD_version >= 800000
|
||||
#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP)
|
||||
#else
|
||||
#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP)
|
||||
#endif
|
||||
|
||||
/* Define the starting Interrupt rate per Queue */
|
||||
#define IGB_INTS_PER_SEC 8000
|
||||
#define IGB_DEFAULT_ITR ((1000000/IGB_INTS_PER_SEC) << 2)
|
||||
|
||||
#define IGB_LINK_ITR 2000
|
||||
#define I210_LINK_DELAY 1000
|
||||
|
||||
/* Precision Time Sync (IEEE 1588) defines */
|
||||
#define ETHERTYPE_IEEE1588 0x88F7
|
||||
#define PICOSECS_PER_TICK 20833
|
||||
#define TSYNC_PORT 319 /* UDP port for the protocol */
|
||||
|
||||
/*
|
||||
* Bus dma allocation structure used by
|
||||
* e1000_dma_malloc and e1000_dma_free.
|
||||
*/
|
||||
struct igb_dma_alloc {
|
||||
bus_addr_t dma_paddr;
|
||||
caddr_t dma_vaddr;
|
||||
bus_dma_tag_t dma_tag;
|
||||
bus_dmamap_t dma_map;
|
||||
bus_dma_segment_t dma_seg;
|
||||
int dma_nseg;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Driver queue struct: this is the interrupt container
|
||||
** for the associated tx and rx ring.
|
||||
*/
|
||||
struct igb_queue {
|
||||
struct adapter *adapter;
|
||||
u32 msix; /* This queue's MSIX vector */
|
||||
u32 eims; /* This queue's EIMS bit */
|
||||
u32 eitr_setting;
|
||||
struct resource *res;
|
||||
void *tag;
|
||||
struct tx_ring *txr;
|
||||
struct rx_ring *rxr;
|
||||
struct task que_task;
|
||||
struct taskqueue *tq;
|
||||
u64 irqs;
|
||||
};
|
||||
|
||||
/*
|
||||
* The transmit ring, one per queue
|
||||
*/
|
||||
struct tx_ring {
|
||||
struct adapter *adapter;
|
||||
struct mtx tx_mtx;
|
||||
u32 me;
|
||||
int watchdog_time;
|
||||
union e1000_adv_tx_desc *tx_base;
|
||||
struct igb_tx_buf *tx_buffers;
|
||||
struct igb_dma_alloc txdma;
|
||||
volatile u16 tx_avail;
|
||||
u16 next_avail_desc;
|
||||
u16 next_to_clean;
|
||||
u16 num_desc;
|
||||
enum {
|
||||
IGB_QUEUE_IDLE = 1,
|
||||
IGB_QUEUE_WORKING = 2,
|
||||
IGB_QUEUE_HUNG = 4,
|
||||
IGB_QUEUE_DEPLETED = 8,
|
||||
} queue_status;
|
||||
u32 txd_cmd;
|
||||
bus_dma_tag_t txtag;
|
||||
char mtx_name[16];
|
||||
#ifndef IGB_LEGACY_TX
|
||||
struct buf_ring *br;
|
||||
struct task txq_task;
|
||||
#endif
|
||||
u32 bytes; /* used for AIM */
|
||||
u32 packets;
|
||||
/* Soft Stats */
|
||||
unsigned long tso_tx;
|
||||
unsigned long no_tx_map_avail;
|
||||
unsigned long no_tx_dma_setup;
|
||||
u64 no_desc_avail;
|
||||
u64 total_packets;
|
||||
};
|
||||
|
||||
/*
|
||||
* Receive ring: one per queue
|
||||
*/
|
||||
struct rx_ring {
|
||||
struct adapter *adapter;
|
||||
u32 me;
|
||||
struct igb_dma_alloc rxdma;
|
||||
union e1000_adv_rx_desc *rx_base;
|
||||
struct lro_ctrl lro;
|
||||
bool lro_enabled;
|
||||
bool hdr_split;
|
||||
struct mtx rx_mtx;
|
||||
char mtx_name[16];
|
||||
u32 next_to_refresh;
|
||||
u32 next_to_check;
|
||||
struct igb_rx_buf *rx_buffers;
|
||||
bus_dma_tag_t htag; /* dma tag for rx head */
|
||||
bus_dma_tag_t ptag; /* dma tag for rx packet */
|
||||
/*
|
||||
* First/last mbuf pointers, for
|
||||
* collecting multisegment RX packets.
|
||||
*/
|
||||
struct mbuf *fmp;
|
||||
struct mbuf *lmp;
|
||||
|
||||
u32 bytes;
|
||||
u32 packets;
|
||||
int rdt;
|
||||
int rdh;
|
||||
|
||||
/* Soft stats */
|
||||
u64 rx_split_packets;
|
||||
u64 rx_discarded;
|
||||
u64 rx_packets;
|
||||
u64 rx_bytes;
|
||||
};
|
||||
|
||||
struct adapter {
|
||||
struct ifnet *ifp;
|
||||
struct e1000_hw hw;
|
||||
|
||||
struct e1000_osdep osdep;
|
||||
device_t dev;
|
||||
struct cdev *led_dev;
|
||||
|
||||
struct resource *pci_mem;
|
||||
struct resource *msix_mem;
|
||||
int memrid;
|
||||
|
||||
/*
|
||||
* Interrupt resources: this set is
|
||||
* either used for legacy, or for Link
|
||||
* when doing MSIX
|
||||
*/
|
||||
void *tag;
|
||||
struct resource *res;
|
||||
|
||||
struct ifmedia media;
|
||||
struct callout timer;
|
||||
int msix;
|
||||
int if_flags;
|
||||
int pause_frames;
|
||||
|
||||
struct mtx core_mtx;
|
||||
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
|
||||
u16 num_vlans;
|
||||
u16 num_queues;
|
||||
|
||||
/*
|
||||
** Shadow VFTA table, this is needed because
|
||||
** the real vlan filter table gets cleared during
|
||||
** a soft reset and the driver needs to be able
|
||||
** to repopulate it.
|
||||
*/
|
||||
u32 shadow_vfta[IGB_VFTA_SIZE];
|
||||
|
||||
/* Info about the interface */
|
||||
u32 optics;
|
||||
u32 fc; /* local flow ctrl setting */
|
||||
int advertise; /* link speeds */
|
||||
bool link_active;
|
||||
u16 max_frame_size;
|
||||
u16 num_segs;
|
||||
u16 link_speed;
|
||||
bool link_up;
|
||||
u32 linkvec;
|
||||
u16 link_duplex;
|
||||
u32 dmac;
|
||||
int link_mask;
|
||||
|
||||
/* Flags */
|
||||
u32 flags;
|
||||
|
||||
/* Mbuf cluster size */
|
||||
u32 rx_mbuf_sz;
|
||||
|
||||
/* Support for pluggable optics */
|
||||
bool sfp_probe;
|
||||
struct task link_task; /* Link tasklet */
|
||||
struct task mod_task; /* SFP tasklet */
|
||||
struct task msf_task; /* Multispeed Fiber */
|
||||
struct taskqueue *tq;
|
||||
|
||||
/*
|
||||
** Queues:
|
||||
** This is the irq holder, it has
|
||||
** and RX/TX pair or rings associated
|
||||
** with it.
|
||||
*/
|
||||
struct igb_queue *queues;
|
||||
|
||||
/*
|
||||
* Transmit rings:
|
||||
* Allocated at run time, an array of rings.
|
||||
*/
|
||||
struct tx_ring *tx_rings;
|
||||
u32 num_tx_desc;
|
||||
|
||||
/*
|
||||
* Receive rings:
|
||||
* Allocated at run time, an array of rings.
|
||||
*/
|
||||
struct rx_ring *rx_rings;
|
||||
u64 que_mask;
|
||||
u32 num_rx_desc;
|
||||
|
||||
/* Multicast array memory */
|
||||
u8 *mta;
|
||||
|
||||
/* Misc stats maintained by the driver */
|
||||
unsigned long device_control;
|
||||
unsigned long dropped_pkts;
|
||||
unsigned long eint_mask;
|
||||
unsigned long int_mask;
|
||||
unsigned long link_irq;
|
||||
unsigned long mbuf_defrag_failed;
|
||||
unsigned long no_tx_dma_setup;
|
||||
unsigned long packet_buf_alloc_rx;
|
||||
unsigned long packet_buf_alloc_tx;
|
||||
unsigned long rx_control;
|
||||
unsigned long rx_overruns;
|
||||
unsigned long watchdog_events;
|
||||
|
||||
/* Used in pf and vf */
|
||||
void *stats;
|
||||
|
||||
int enable_aim;
|
||||
int has_manage;
|
||||
int wol;
|
||||
int rx_process_limit;
|
||||
int tx_process_limit;
|
||||
u16 vf_ifp; /* a VF interface */
|
||||
bool in_detach; /* Used only in igb_ioctl */
|
||||
|
||||
};
|
||||
|
||||
/* ******************************************************************************
|
||||
* vendor_info_array
|
||||
*
|
||||
* This array contains the list of Subvendor/Subdevice IDs on which the driver
|
||||
* should load.
|
||||
*
|
||||
* ******************************************************************************/
|
||||
typedef struct _igb_vendor_info_t {
|
||||
unsigned int vendor_id;
|
||||
unsigned int device_id;
|
||||
unsigned int subvendor_id;
|
||||
unsigned int subdevice_id;
|
||||
unsigned int index;
|
||||
} igb_vendor_info_t;
|
||||
|
||||
struct igb_tx_buf {
|
||||
union e1000_adv_tx_desc *eop;
|
||||
struct mbuf *m_head;
|
||||
bus_dmamap_t map;
|
||||
};
|
||||
|
||||
struct igb_rx_buf {
|
||||
struct mbuf *m_head;
|
||||
struct mbuf *m_pack;
|
||||
bus_dmamap_t hmap; /* bus_dma map for header */
|
||||
bus_dmamap_t pmap; /* bus_dma map for packet */
|
||||
};
|
||||
|
||||
/*
|
||||
** Find the number of unrefreshed RX descriptors
|
||||
*/
|
||||
static inline u16
|
||||
igb_rx_unrefreshed(struct rx_ring *rxr)
|
||||
{
|
||||
struct adapter *adapter = rxr->adapter;
|
||||
|
||||
if (rxr->next_to_check > rxr->next_to_refresh)
|
||||
return (rxr->next_to_check - rxr->next_to_refresh - 1);
|
||||
else
|
||||
return ((adapter->num_rx_desc + rxr->next_to_check) -
|
||||
rxr->next_to_refresh - 1);
|
||||
}
|
||||
|
||||
#define IGB_CORE_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->core_mtx, _name, "IGB Core Lock", MTX_DEF)
|
||||
#define IGB_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx)
|
||||
#define IGB_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
|
||||
#define IGB_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
|
||||
#define IGB_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
|
||||
|
||||
#define IGB_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx)
|
||||
#define IGB_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
|
||||
#define IGB_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
|
||||
#define IGB_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx)
|
||||
#define IGB_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
|
||||
|
||||
#define IGB_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
|
||||
#define IGB_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
|
||||
#define IGB_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
|
||||
#define IGB_RX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rx_mtx, MA_OWNED)
|
||||
|
||||
#define UPDATE_VF_REG(reg, last, cur) \
|
||||
{ \
|
||||
u32 new = E1000_READ_REG(hw, reg); \
|
||||
if (new < last) \
|
||||
cur += 0x100000000LL; \
|
||||
last = new; \
|
||||
cur &= 0xFFFFFFFF00000000LL; \
|
||||
cur |= new; \
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 800000 && __FreeBSD_version < 800504
|
||||
static __inline int
|
||||
drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
|
||||
{
|
||||
#ifdef ALTQ
|
||||
if (ALTQ_IS_ENABLED(&ifp->if_snd))
|
||||
return (1);
|
||||
#endif
|
||||
return (!buf_ring_empty(br));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _IF_IGB_H_ */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,519 +0,0 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2015, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _LEM_H_DEFINED_
|
||||
#define _LEM_H_DEFINED_
|
||||
|
||||
|
||||
/* Tunables */
|
||||
|
||||
/*
|
||||
* EM_TXD: Maximum number of Transmit Descriptors
|
||||
* Valid Range: 80-256 for 82542 and 82543-based adapters
|
||||
* 80-4096 for others
|
||||
* Default Value: 256
|
||||
* This value is the number of transmit descriptors allocated by the driver.
|
||||
* Increasing this value allows the driver to queue more transmits. Each
|
||||
* descriptor is 16 bytes.
|
||||
* Since TDLEN should be multiple of 128bytes, the number of transmit
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_TXD 80
|
||||
#define EM_MAX_TXD_82543 256
|
||||
#define EM_MAX_TXD 4096
|
||||
#define EM_DEFAULT_TXD EM_MAX_TXD_82543
|
||||
|
||||
/*
|
||||
* EM_RXD - Maximum number of receive Descriptors
|
||||
* Valid Range: 80-256 for 82542 and 82543-based adapters
|
||||
* 80-4096 for others
|
||||
* Default Value: 256
|
||||
* This value is the number of receive descriptors allocated by the driver.
|
||||
* Increasing this value allows the driver to buffer more incoming packets.
|
||||
* Each descriptor is 16 bytes. A receive buffer is also allocated for each
|
||||
* descriptor. The maximum MTU size is 16110.
|
||||
* Since TDLEN should be multiple of 128bytes, the number of transmit
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_RXD 80
|
||||
#define EM_MAX_RXD_82543 256
|
||||
#define EM_MAX_RXD 4096
|
||||
#define EM_DEFAULT_RXD EM_MAX_RXD_82543
|
||||
|
||||
/*
|
||||
* EM_TIDV - Transmit Interrupt Delay Value
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value delays the generation of transmit interrupts in units of
|
||||
* 1.024 microseconds. Transmit interrupt reduction can improve CPU
|
||||
* efficiency if properly tuned for specific network traffic. If the
|
||||
* system is reporting dropped transmits, this value may be set too high
|
||||
* causing the driver to run out of available transmit descriptors.
|
||||
*/
|
||||
#define EM_TIDV 64
|
||||
|
||||
/*
|
||||
* EM_TADV - Transmit Absolute Interrupt Delay Value
|
||||
* (Not valid for 82542/82543/82544)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value, in units of 1.024 microseconds, limits the delay in which a
|
||||
* transmit interrupt is generated. Useful only if EM_TIDV is non-zero,
|
||||
* this value ensures that an interrupt is generated after the initial
|
||||
* packet is sent on the wire within the set amount of time. Proper tuning,
|
||||
* along with EM_TIDV, may improve traffic throughput in specific
|
||||
* network conditions.
|
||||
*/
|
||||
#define EM_TADV 64
|
||||
|
||||
/*
|
||||
* EM_RDTR - Receive Interrupt Delay Timer (Packet Timer)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 0
|
||||
* This value delays the generation of receive interrupts in units of 1.024
|
||||
* microseconds. Receive interrupt reduction can improve CPU efficiency if
|
||||
* properly tuned for specific network traffic. Increasing this value adds
|
||||
* extra latency to frame reception and can end up decreasing the throughput
|
||||
* of TCP traffic. If the system is reporting dropped receives, this value
|
||||
* may be set too high, causing the driver to run out of available receive
|
||||
* descriptors.
|
||||
*
|
||||
* CAUTION: When setting EM_RDTR to a value other than 0, adapters
|
||||
* may hang (stop transmitting) under certain network conditions.
|
||||
* If this occurs a WATCHDOG message is logged in the system
|
||||
* event log. In addition, the controller is automatically reset,
|
||||
* restoring the network connection. To eliminate the potential
|
||||
* for the hang ensure that EM_RDTR is set to 0.
|
||||
*/
|
||||
#define EM_RDTR 0
|
||||
|
||||
/*
|
||||
* Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value, in units of 1.024 microseconds, limits the delay in which a
|
||||
* receive interrupt is generated. Useful only if EM_RDTR is non-zero,
|
||||
* this value ensures that an interrupt is generated after the initial
|
||||
* packet is received within the set amount of time. Proper tuning,
|
||||
* along with EM_RDTR, may improve traffic throughput in specific network
|
||||
* conditions.
|
||||
*/
|
||||
#define EM_RADV 64
|
||||
|
||||
/*
|
||||
* This parameter controls the max duration of transmit watchdog.
|
||||
*/
|
||||
#define EM_WATCHDOG (10 * hz)
|
||||
|
||||
/*
|
||||
* This parameter controls when the driver calls the routine to reclaim
|
||||
* transmit descriptors.
|
||||
*/
|
||||
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
|
||||
#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
|
||||
|
||||
/*
|
||||
* This parameter controls whether or not autonegotation is enabled.
|
||||
* 0 - Disable autonegotiation
|
||||
* 1 - Enable autonegotiation
|
||||
*/
|
||||
#define DO_AUTO_NEG 1
|
||||
|
||||
/*
|
||||
* This parameter control whether or not the driver will wait for
|
||||
* autonegotiation to complete.
|
||||
* 1 - Wait for autonegotiation to complete
|
||||
* 0 - Don't wait for autonegotiation to complete
|
||||
*/
|
||||
#define WAIT_FOR_AUTO_NEG_DEFAULT 0
|
||||
|
||||
/* Tunables -- End */
|
||||
|
||||
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
|
||||
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
|
||||
ADVERTISE_1000_FULL)
|
||||
|
||||
#define AUTO_ALL_MODES 0
|
||||
|
||||
/* PHY master/slave setting */
|
||||
#define EM_MASTER_SLAVE e1000_ms_hw_default
|
||||
|
||||
/*
|
||||
* Micellaneous constants
|
||||
*/
|
||||
#define EM_VENDOR_ID 0x8086
|
||||
#define EM_FLASH 0x0014
|
||||
|
||||
#define EM_JUMBO_PBA 0x00000028
|
||||
#define EM_DEFAULT_PBA 0x00000030
|
||||
#define EM_SMARTSPEED_DOWNSHIFT 3
|
||||
#define EM_SMARTSPEED_MAX 15
|
||||
#define EM_MAX_LOOP 10
|
||||
|
||||
#define MAX_NUM_MULTICAST_ADDRESSES 128
|
||||
#define PCI_ANY_ID (~0U)
|
||||
#define ETHER_ALIGN 2
|
||||
#define EM_FC_PAUSE_TIME 0x0680
|
||||
#define EM_EEPROM_APME 0x400;
|
||||
#define EM_82544_APME 0x0004;
|
||||
|
||||
/* Code compatilbility between 6 and 7 */
|
||||
#ifndef ETHER_BPF_MTAP
|
||||
#define ETHER_BPF_MTAP BPF_MTAP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
|
||||
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
|
||||
* also optimize cache line size effect. H/W supports up to cache line size 128.
|
||||
*/
|
||||
#define EM_DBA_ALIGN 128
|
||||
|
||||
#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
|
||||
|
||||
/* PCI Config defines */
|
||||
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
|
||||
#define EM_BAR_TYPE_MASK 0x00000001
|
||||
#define EM_BAR_TYPE_MMEM 0x00000000
|
||||
#define EM_BAR_TYPE_IO 0x00000001
|
||||
#define EM_BAR_TYPE_FLASH 0x0014
|
||||
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
|
||||
#define EM_BAR_MEM_TYPE_MASK 0x00000006
|
||||
#define EM_BAR_MEM_TYPE_32BIT 0x00000000
|
||||
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
|
||||
#define EM_MSIX_BAR 3 /* On 82575 */
|
||||
|
||||
#if __FreeBSD_version < 900000
|
||||
#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD
|
||||
#endif
|
||||
|
||||
/* Defines for printing debug information */
|
||||
#define DEBUG_INIT 0
|
||||
#define DEBUG_IOCTL 0
|
||||
#define DEBUG_HW 0
|
||||
|
||||
#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
|
||||
#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
|
||||
#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
|
||||
#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
|
||||
#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
|
||||
#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
|
||||
#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
|
||||
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
|
||||
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
|
||||
|
||||
#define EM_MAX_SCATTER 40
|
||||
#define EM_VFTA_SIZE 128
|
||||
#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */
|
||||
#define ETH_ZLEN 60
|
||||
#define ETH_ADDR_LEN 6
|
||||
#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
|
||||
|
||||
/*
|
||||
* 82574 has a nonstandard address for EIAC
|
||||
* and since its only used in MSIX, and in
|
||||
* the em driver only 82574 uses MSIX we can
|
||||
* solve it just using this define.
|
||||
*/
|
||||
#define EM_EIAC 0x000DC
|
||||
|
||||
/* Used in for 82547 10Mb Half workaround */
|
||||
#define EM_PBA_BYTES_SHIFT 0xA
|
||||
#define EM_TX_HEAD_ADDR_SHIFT 7
|
||||
#define EM_PBA_TX_MASK 0xFFFF0000
|
||||
#define EM_FIFO_HDR 0x10
|
||||
#define EM_82547_PKT_THRESH 0x3e0
|
||||
|
||||
/* Precision Time Sync (IEEE 1588) defines */
|
||||
#define ETHERTYPE_IEEE1588 0x88F7
|
||||
#define PICOSECS_PER_TICK 20833
|
||||
#define TSYNC_PORT 319 /* UDP port for the protocol */
|
||||
|
||||
#ifdef NIC_PARAVIRT
|
||||
#define E1000_PARA_SUBDEV 0x1101 /* special id */
|
||||
#define E1000_CSBAL 0x02830 /* csb phys. addr. low */
|
||||
#define E1000_CSBAH 0x02834 /* csb phys. addr. hi */
|
||||
#include <net/paravirt.h>
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
/*
|
||||
* Bus dma allocation structure used by
|
||||
* e1000_dma_malloc and e1000_dma_free.
|
||||
*/
|
||||
struct em_dma_alloc {
|
||||
bus_addr_t dma_paddr;
|
||||
caddr_t dma_vaddr;
|
||||
bus_dma_tag_t dma_tag;
|
||||
bus_dmamap_t dma_map;
|
||||
bus_dma_segment_t dma_seg;
|
||||
int dma_nseg;
|
||||
};
|
||||
|
||||
struct adapter;
|
||||
|
||||
struct em_int_delay_info {
|
||||
struct adapter *adapter; /* Back-pointer to the adapter struct */
|
||||
int offset; /* Register offset to read/write */
|
||||
int value; /* Current value in usecs */
|
||||
};
|
||||
|
||||
/* Our adapter structure */
|
||||
struct adapter {
|
||||
if_t ifp;
|
||||
struct e1000_hw hw;
|
||||
|
||||
/* FreeBSD operating-system-specific structures. */
|
||||
struct e1000_osdep osdep;
|
||||
device_t dev;
|
||||
struct cdev *led_dev;
|
||||
|
||||
struct resource *memory;
|
||||
struct resource *flash;
|
||||
struct resource *msix;
|
||||
|
||||
struct resource *ioport;
|
||||
int io_rid;
|
||||
|
||||
/* 82574 may use 3 int vectors */
|
||||
struct resource *res[3];
|
||||
void *tag[3];
|
||||
int rid[3];
|
||||
|
||||
struct ifmedia media;
|
||||
struct callout timer;
|
||||
struct callout tx_fifo_timer;
|
||||
bool watchdog_check;
|
||||
int watchdog_time;
|
||||
int msi;
|
||||
int if_flags;
|
||||
int max_frame_size;
|
||||
int min_frame_size;
|
||||
struct mtx core_mtx;
|
||||
struct mtx tx_mtx;
|
||||
struct mtx rx_mtx;
|
||||
int em_insert_vlan_header;
|
||||
|
||||
/* Task for FAST handling */
|
||||
struct task link_task;
|
||||
struct task rxtx_task;
|
||||
struct task rx_task;
|
||||
struct task tx_task;
|
||||
struct taskqueue *tq; /* private task queue */
|
||||
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
u32 num_vlans;
|
||||
|
||||
/* Management and WOL features */
|
||||
u32 wol;
|
||||
bool has_manage;
|
||||
bool has_amt;
|
||||
|
||||
/* Multicast array memory */
|
||||
u8 *mta;
|
||||
|
||||
/*
|
||||
** Shadow VFTA table, this is needed because
|
||||
** the real vlan filter table gets cleared during
|
||||
** a soft reset and the driver needs to be able
|
||||
** to repopulate it.
|
||||
*/
|
||||
u32 shadow_vfta[EM_VFTA_SIZE];
|
||||
|
||||
/* Info about the interface */
|
||||
uint8_t link_active;
|
||||
uint16_t link_speed;
|
||||
uint16_t link_duplex;
|
||||
uint32_t smartspeed;
|
||||
uint32_t fc_setting;
|
||||
|
||||
struct em_int_delay_info tx_int_delay;
|
||||
struct em_int_delay_info tx_abs_int_delay;
|
||||
struct em_int_delay_info rx_int_delay;
|
||||
struct em_int_delay_info rx_abs_int_delay;
|
||||
struct em_int_delay_info tx_itr;
|
||||
|
||||
/*
|
||||
* Transmit definitions
|
||||
*
|
||||
* We have an array of num_tx_desc descriptors (handled
|
||||
* by the controller) paired with an array of tx_buffers
|
||||
* (at tx_buffer_area).
|
||||
* The index of the next available descriptor is next_avail_tx_desc.
|
||||
* The number of remaining tx_desc is num_tx_desc_avail.
|
||||
*/
|
||||
struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
|
||||
struct e1000_tx_desc *tx_desc_base;
|
||||
uint32_t next_avail_tx_desc;
|
||||
uint32_t next_tx_to_clean;
|
||||
volatile uint16_t num_tx_desc_avail;
|
||||
uint16_t num_tx_desc;
|
||||
uint16_t last_hw_offload;
|
||||
uint32_t txd_cmd;
|
||||
struct em_buffer *tx_buffer_area;
|
||||
bus_dma_tag_t txtag; /* dma tag for tx */
|
||||
uint32_t tx_tso; /* last tx was tso */
|
||||
|
||||
/*
|
||||
* Receive definitions
|
||||
*
|
||||
* we have an array of num_rx_desc rx_desc (handled by the
|
||||
* controller), and paired with an array of rx_buffers
|
||||
* (at rx_buffer_area).
|
||||
* The next pair to check on receive is at offset next_rx_desc_to_check
|
||||
*/
|
||||
struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
|
||||
struct e1000_rx_desc *rx_desc_base;
|
||||
uint32_t next_rx_desc_to_check;
|
||||
uint32_t rx_buffer_len;
|
||||
uint16_t num_rx_desc;
|
||||
int rx_process_limit;
|
||||
struct em_buffer *rx_buffer_area;
|
||||
bus_dma_tag_t rxtag;
|
||||
bus_dmamap_t rx_sparemap;
|
||||
|
||||
/*
|
||||
* First/last mbuf pointers, for
|
||||
* collecting multisegment RX packets.
|
||||
*/
|
||||
struct mbuf *fmp;
|
||||
struct mbuf *lmp;
|
||||
|
||||
/* Misc stats maintained by the driver */
|
||||
unsigned long dropped_pkts;
|
||||
unsigned long link_irq;
|
||||
unsigned long mbuf_cluster_failed;
|
||||
unsigned long mbuf_defrag_failed;
|
||||
unsigned long no_tx_desc_avail1;
|
||||
unsigned long no_tx_desc_avail2;
|
||||
unsigned long no_tx_dma_setup;
|
||||
unsigned long no_tx_map_avail;
|
||||
unsigned long watchdog_events;
|
||||
unsigned long rx_irq;
|
||||
unsigned long rx_overruns;
|
||||
unsigned long tx_irq;
|
||||
|
||||
/* 82547 workaround */
|
||||
uint32_t tx_fifo_size;
|
||||
uint32_t tx_fifo_head;
|
||||
uint32_t tx_fifo_head_addr;
|
||||
uint64_t tx_fifo_reset_cnt;
|
||||
uint64_t tx_fifo_wrk_cnt;
|
||||
uint32_t tx_head_addr;
|
||||
|
||||
/* For 82544 PCIX Workaround */
|
||||
boolean_t pcix_82544;
|
||||
boolean_t in_detach;
|
||||
|
||||
#ifdef NIC_SEND_COMBINING
|
||||
/* 0 = idle; 1xxxx int-pending; 3xxxx int + d pending + tdt */
|
||||
#define MIT_PENDING_INT 0x10000 /* pending interrupt */
|
||||
#define MIT_PENDING_TDT 0x30000 /* both intr and tdt write are pending */
|
||||
uint32_t shadow_tdt;
|
||||
uint32_t sc_enable;
|
||||
#endif /* NIC_SEND_COMBINING */
|
||||
#ifdef BATCH_DISPATCH
|
||||
uint32_t batch_enable;
|
||||
#endif /* BATCH_DISPATCH */
|
||||
|
||||
#ifdef NIC_PARAVIRT
|
||||
struct em_dma_alloc csb_mem; /* phys address */
|
||||
struct paravirt_csb *csb; /* virtual addr */
|
||||
uint32_t rx_retries; /* optimize rx loop */
|
||||
uint32_t tdt_csb_count;// XXX stat
|
||||
uint32_t tdt_reg_count;// XXX stat
|
||||
uint32_t tdt_int_count;// XXX stat
|
||||
uint32_t guest_need_kick_count;// XXX stat
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
struct e1000_hw_stats stats;
|
||||
};
|
||||
|
||||
/* ******************************************************************************
|
||||
* vendor_info_array
|
||||
*
|
||||
* This array contains the list of Subvendor/Subdevice IDs on which the driver
|
||||
* should load.
|
||||
*
|
||||
* ******************************************************************************/
|
||||
typedef struct _em_vendor_info_t {
|
||||
unsigned int vendor_id;
|
||||
unsigned int device_id;
|
||||
unsigned int subvendor_id;
|
||||
unsigned int subdevice_id;
|
||||
unsigned int index;
|
||||
} em_vendor_info_t;
|
||||
|
||||
struct em_buffer {
|
||||
int next_eop; /* Index of the desc to watch */
|
||||
struct mbuf *m_head;
|
||||
bus_dmamap_t map; /* bus_dma map for packet */
|
||||
};
|
||||
|
||||
/* For 82544 PCIX Workaround */
|
||||
typedef struct _ADDRESS_LENGTH_PAIR
|
||||
{
|
||||
uint64_t address;
|
||||
uint32_t length;
|
||||
} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
|
||||
|
||||
typedef struct _DESCRIPTOR_PAIR
|
||||
{
|
||||
ADDRESS_LENGTH_PAIR descriptor[4];
|
||||
uint32_t elements;
|
||||
} DESC_ARRAY, *PDESC_ARRAY;
|
||||
|
||||
#define EM_CORE_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
|
||||
#define EM_TX_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->tx_mtx, _name, "EM TX Lock", MTX_DEF)
|
||||
#define EM_RX_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->rx_mtx, _name, "EM RX Lock", MTX_DEF)
|
||||
#define EM_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx)
|
||||
#define EM_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx)
|
||||
#define EM_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
|
||||
#define EM_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
|
||||
#define EM_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
|
||||
#define EM_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx)
|
||||
#define EM_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
|
||||
#define EM_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
|
||||
#define EM_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
|
||||
#define EM_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
|
||||
#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
|
||||
#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
|
||||
|
||||
#endif /* _LEM_H_DEFINED_ */
|
594
sys/dev/e1000/igb_txrx.c
Normal file
594
sys/dev/e1000/igb_txrx.c
Normal file
@ -0,0 +1,594 @@
|
||||
/* $FreeBSD$ */
|
||||
#include "if_em.h"
|
||||
|
||||
#ifdef RSS
|
||||
#include <net/rss_config.h>
|
||||
#include <netinet/in_rss.h>
|
||||
#endif
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
#define DPRINTF device_printf
|
||||
#else
|
||||
#define DPRINTF(...)
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* Local Function prototypes
|
||||
*********************************************************************/
|
||||
static int igb_isc_txd_encap(void *arg, if_pkt_info_t pi);
|
||||
static void igb_isc_txd_flush(void *arg, uint16_t txqid, uint32_t pidx);
|
||||
static int igb_isc_txd_credits_update(void *arg, uint16_t txqid, uint32_t cidx, bool clear);
|
||||
|
||||
static void igb_isc_rxd_refill(void *arg, uint16_t rxqid, uint8_t flid __unused,
|
||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs __unused, uint16_t count, uint16_t buf_len __unused);
|
||||
static void igb_isc_rxd_flush(void *arg, uint16_t rxqid, uint8_t flid __unused, uint32_t pidx);
|
||||
static int igb_isc_rxd_available(void *arg, uint16_t rxqid, uint32_t idx,
|
||||
int budget);
|
||||
static int igb_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri);
|
||||
|
||||
static int igb_tx_ctx_setup(struct tx_ring *txr, if_pkt_info_t pi, u32 *cmd_type_len, u32 *olinfo_status);
|
||||
static int igb_tso_setup(struct tx_ring *txr, if_pkt_info_t pi, u32 *cmd_type_len, u32 *olinfo_status);
|
||||
|
||||
static void igb_rx_checksum(u32 staterr, if_rxd_info_t ri, u32 ptype);
|
||||
static int igb_determine_rsstype(u16 pkt_info);
|
||||
|
||||
extern void igb_if_enable_intr(if_ctx_t ctx);
|
||||
extern int em_intr(void *arg);
|
||||
|
||||
struct if_txrx igb_txrx = {
|
||||
igb_isc_txd_encap,
|
||||
igb_isc_txd_flush,
|
||||
igb_isc_txd_credits_update,
|
||||
igb_isc_rxd_available,
|
||||
igb_isc_rxd_pkt_get,
|
||||
igb_isc_rxd_refill,
|
||||
igb_isc_rxd_flush,
|
||||
em_intr
|
||||
};
|
||||
|
||||
extern if_shared_ctx_t em_sctx;
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Setup work for hardware segmentation offload (TSO) on
|
||||
* adapters using advanced tx descriptors
|
||||
*
|
||||
**********************************************************************/
|
||||
static int
|
||||
igb_tso_setup(struct tx_ring *txr, if_pkt_info_t pi, u32 *cmd_type_len, u32 *olinfo_status)
|
||||
{
|
||||
struct e1000_adv_tx_context_desc *TXD;
|
||||
struct adapter *adapter = txr->adapter;
|
||||
u32 type_tucmd_mlhl = 0, vlan_macip_lens = 0;
|
||||
u32 mss_l4len_idx = 0;
|
||||
u32 paylen;
|
||||
|
||||
switch(pi->ipi_etype) {
|
||||
case ETHERTYPE_IPV6:
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6;
|
||||
break;
|
||||
case ETHERTYPE_IP:
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4;
|
||||
/* Tell transmit desc to also do IPv4 checksum. */
|
||||
*olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
|
||||
break;
|
||||
default:
|
||||
panic("%s: CSUM_TSO but no supported IP version (0x%04x)",
|
||||
__func__, ntohs(pi->ipi_etype));
|
||||
break;
|
||||
}
|
||||
|
||||
TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[pi->ipi_pidx];
|
||||
|
||||
/* This is used in the transmit desc in encap */
|
||||
paylen = pi->ipi_len - pi->ipi_ehdrlen - pi->ipi_ip_hlen - pi->ipi_tcp_hlen;
|
||||
|
||||
/* VLAN MACLEN IPLEN */
|
||||
if (pi->ipi_mflags & M_VLANTAG) {
|
||||
vlan_macip_lens |= (pi->ipi_vtag << E1000_ADVTXD_VLAN_SHIFT);
|
||||
}
|
||||
|
||||
vlan_macip_lens |= pi->ipi_ehdrlen << E1000_ADVTXD_MACLEN_SHIFT;
|
||||
vlan_macip_lens |= pi->ipi_ip_hlen;
|
||||
TXD->vlan_macip_lens = htole32(vlan_macip_lens);
|
||||
|
||||
/* ADV DTYPE TUCMD */
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DTYP_CTXT;
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_TCP;
|
||||
TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
|
||||
|
||||
/* MSS L4LEN IDX */
|
||||
mss_l4len_idx |= (pi->ipi_tso_segsz << E1000_ADVTXD_MSS_SHIFT);
|
||||
mss_l4len_idx |= (pi->ipi_tcp_hlen << E1000_ADVTXD_L4LEN_SHIFT);
|
||||
/* 82575 needs the queue index added */
|
||||
if (adapter->hw.mac.type == e1000_82575)
|
||||
mss_l4len_idx |= txr->me << 4;
|
||||
TXD->mss_l4len_idx = htole32(mss_l4len_idx);
|
||||
|
||||
TXD->seqnum_seed = htole32(0);
|
||||
*cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
|
||||
*olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
|
||||
*olinfo_status |= paylen << E1000_ADVTXD_PAYLEN_SHIFT;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Advanced Context Descriptor setup for VLAN, CSUM or TSO
|
||||
*
|
||||
**********************************************************************/
|
||||
static int
|
||||
igb_tx_ctx_setup(struct tx_ring *txr, if_pkt_info_t pi, u32 *cmd_type_len, u32 *olinfo_status)
|
||||
{
|
||||
struct e1000_adv_tx_context_desc *TXD;
|
||||
struct adapter *adapter = txr->adapter;
|
||||
u32 vlan_macip_lens, type_tucmd_mlhl;
|
||||
u32 mss_l4len_idx;
|
||||
mss_l4len_idx = vlan_macip_lens = type_tucmd_mlhl = 0;
|
||||
int offload = TRUE;
|
||||
|
||||
/* First check if TSO is to be used */
|
||||
if (pi->ipi_csum_flags & CSUM_TSO)
|
||||
return (igb_tso_setup(txr, pi, cmd_type_len, olinfo_status));
|
||||
|
||||
/* Indicate the whole packet as payload when not doing TSO */
|
||||
*olinfo_status |= pi->ipi_len << E1000_ADVTXD_PAYLEN_SHIFT;
|
||||
|
||||
/* Now ready a context descriptor */
|
||||
TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[pi->ipi_pidx];
|
||||
|
||||
/*
|
||||
** In advanced descriptors the vlan tag must
|
||||
** be placed into the context descriptor. Hence
|
||||
** we need to make one even if not doing offloads.
|
||||
*/
|
||||
if (pi->ipi_mflags & M_VLANTAG) {
|
||||
vlan_macip_lens |= (pi->ipi_vtag << E1000_ADVTXD_VLAN_SHIFT);
|
||||
} else if ((pi->ipi_csum_flags & CSUM_OFFLOAD) == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Set the ether header length */
|
||||
vlan_macip_lens |= pi->ipi_ehdrlen << E1000_ADVTXD_MACLEN_SHIFT;
|
||||
|
||||
switch(pi->ipi_etype) {
|
||||
case ETHERTYPE_IP:
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4;
|
||||
break;
|
||||
case ETHERTYPE_IPV6:
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6;
|
||||
break;
|
||||
default:
|
||||
offload = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
vlan_macip_lens |= pi->ipi_ip_hlen;
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DTYP_CTXT;
|
||||
|
||||
switch (pi->ipi_ipproto) {
|
||||
case IPPROTO_TCP:
|
||||
#if __FreeBSD_version >= 1000000
|
||||
if (pi->ipi_csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP))
|
||||
#else
|
||||
if (pi->ipi_csum_flags & CSUM_TCP)
|
||||
#endif
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_TCP;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
#if __FreeBSD_version >= 1000000
|
||||
if (pi->ipi_csum_flags & (CSUM_IP_UDP | CSUM_IP6_UDP))
|
||||
#else
|
||||
if (pi->ipi_csum_flags & CSUM_UDP)
|
||||
#endif
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_UDP;
|
||||
break;
|
||||
|
||||
#if __FreeBSD_version >= 800000
|
||||
case IPPROTO_SCTP:
|
||||
#if __FreeBSD_version >= 1000000
|
||||
if (pi->ipi_csum_flags & (CSUM_IP_SCTP | CSUM_IP6_SCTP))
|
||||
#else
|
||||
if (pi->ipi_csum_flags & CSUM_SCTP)
|
||||
#endif
|
||||
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_SCTP;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
offload = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (offload) /* For the TX descriptor setup */
|
||||
*olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
|
||||
|
||||
/* 82575 needs the queue index added */
|
||||
if (adapter->hw.mac.type == e1000_82575)
|
||||
mss_l4len_idx = txr->me << 4;
|
||||
|
||||
/* Now copy bits into descriptor */
|
||||
TXD->vlan_macip_lens = htole32(vlan_macip_lens);
|
||||
TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
|
||||
TXD->seqnum_seed = htole32(0);
|
||||
TXD->mss_l4len_idx = htole32(mss_l4len_idx);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
igb_isc_txd_encap(void *arg, if_pkt_info_t pi)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_tx_queue *que = &sc->tx_queues[pi->ipi_qsidx];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
int nsegs = pi->ipi_nsegs;
|
||||
bus_dma_segment_t *segs = pi->ipi_segs;
|
||||
struct em_txbuffer *txbuf;
|
||||
union e1000_adv_tx_desc *txd = NULL;
|
||||
|
||||
int i, j, first, pidx_last;
|
||||
u32 olinfo_status, cmd_type_len;
|
||||
|
||||
pidx_last = olinfo_status = 0;
|
||||
/* Basic descriptor defines */
|
||||
cmd_type_len = (E1000_ADVTXD_DTYP_DATA |
|
||||
E1000_ADVTXD_DCMD_IFCS | E1000_ADVTXD_DCMD_DEXT);
|
||||
|
||||
if (pi->ipi_mflags & M_VLANTAG)
|
||||
cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
|
||||
|
||||
first = i = pi->ipi_pidx;
|
||||
|
||||
/* Consume the first descriptor */
|
||||
i += igb_tx_ctx_setup(txr, pi, &cmd_type_len, &olinfo_status);
|
||||
if (i == scctx->isc_ntxd[0])
|
||||
i = 0;
|
||||
|
||||
/* 82575 needs the queue index added */
|
||||
if (sc->hw.mac.type == e1000_82575)
|
||||
olinfo_status |= txr->me << 4;
|
||||
|
||||
for (j = 0; j < nsegs; j++) {
|
||||
bus_size_t seglen;
|
||||
bus_addr_t segaddr;
|
||||
|
||||
txbuf = &txr->tx_buffers[i];
|
||||
txd = (union e1000_adv_tx_desc *)&txr->tx_base[i];
|
||||
seglen = segs[j].ds_len;
|
||||
segaddr = htole64(segs[j].ds_addr);
|
||||
|
||||
txd->read.buffer_addr = segaddr;
|
||||
txd->read.cmd_type_len = htole32(E1000_TXD_CMD_IFCS |
|
||||
cmd_type_len | seglen);
|
||||
txd->read.olinfo_status = htole32(olinfo_status);
|
||||
pidx_last = i;
|
||||
if (++i == scctx->isc_ntxd[0]) {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
txd->read.cmd_type_len |=
|
||||
htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS);
|
||||
|
||||
/* Set the EOP descriptor that will be marked done */
|
||||
txbuf = &txr->tx_buffers[first];
|
||||
txbuf->eop = pidx_last;
|
||||
|
||||
pi->ipi_new_pidx = i;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
igb_isc_txd_flush(void *arg, uint16_t txqid, uint32_t pidx)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
struct em_tx_queue *que = &adapter->tx_queues[txqid];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), pidx);
|
||||
}
|
||||
|
||||
static int
|
||||
igb_isc_txd_credits_update(void *arg, uint16_t txqid, uint32_t cidx_init, bool clear)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
if_softc_ctx_t scctx = adapter->shared;
|
||||
struct em_tx_queue *que = &adapter->tx_queues[txqid];
|
||||
struct tx_ring *txr = &que->txr;
|
||||
|
||||
u32 cidx, ntxd, processed = 0;
|
||||
|
||||
struct em_txbuffer *buf;
|
||||
union e1000_adv_tx_desc *txd, *eop;
|
||||
int limit;
|
||||
|
||||
cidx = cidx_init;
|
||||
|
||||
buf = &txr->tx_buffers[cidx];
|
||||
txd = (union e1000_adv_tx_desc *)&txr->tx_base[cidx];
|
||||
ntxd = scctx->isc_ntxd[0];
|
||||
limit = adapter->tx_process_limit;
|
||||
|
||||
do {
|
||||
if (buf->eop == -1) /* No work */
|
||||
break;
|
||||
|
||||
eop = (union e1000_adv_tx_desc *)&txr->tx_base[buf->eop];
|
||||
if ((eop->wb.status & E1000_TXD_STAT_DD) == 0)
|
||||
break; /* I/O not complete */
|
||||
|
||||
if (clear)
|
||||
buf->eop = -1; /* clear indicate processed */
|
||||
|
||||
/* We clean the range if multi segment */
|
||||
while (txd != eop) {
|
||||
++txd;
|
||||
++buf;
|
||||
/* wrap the ring? */
|
||||
if (++cidx == scctx->isc_ntxd[0]) {
|
||||
cidx = 0;
|
||||
buf = txr->tx_buffers;
|
||||
txd = (union e1000_adv_tx_desc *)txr->tx_base;
|
||||
}
|
||||
|
||||
buf = &txr->tx_buffers[cidx];
|
||||
if (clear)
|
||||
buf->eop = -1;
|
||||
processed++;
|
||||
}
|
||||
processed++;
|
||||
|
||||
/* Try the next packet */
|
||||
txd++;
|
||||
buf++;
|
||||
|
||||
/* reset with a wrap */
|
||||
if (++cidx == scctx->isc_ntxd[0]) {
|
||||
cidx = 0;
|
||||
buf = txr->tx_buffers;
|
||||
txd = (union e1000_adv_tx_desc *)txr->tx_base;
|
||||
}
|
||||
prefetch(txd);
|
||||
prefetch(txd+1);
|
||||
} while (__predict_true(--limit) && cidx != cidx_init);
|
||||
|
||||
return (processed);
|
||||
}
|
||||
|
||||
static void
|
||||
igb_isc_rxd_refill(void *arg, uint16_t rxqid, uint8_t flid __unused,
|
||||
uint32_t pidx, uint64_t *paddrs, caddr_t *vaddrs __unused,
|
||||
uint16_t count, uint16_t buf_len __unused)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
union e1000_adv_rx_desc *rxd;
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
int i;
|
||||
uint32_t next_pidx;
|
||||
|
||||
for (i = 0, next_pidx = pidx; i < count; i++) {
|
||||
rxd = (union e1000_adv_rx_desc *)&rxr->rx_base[next_pidx];
|
||||
|
||||
rxd->read.pkt_addr = htole64(paddrs[i]);
|
||||
if (++next_pidx == scctx->isc_nrxd[0])
|
||||
next_pidx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
igb_isc_rxd_flush(void *arg, uint16_t rxqid, uint8_t flid __unused, uint32_t pidx)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
|
||||
E1000_WRITE_REG(&sc->hw, E1000_RDT(rxr->me), pidx);
|
||||
}
|
||||
|
||||
static int
|
||||
igb_isc_rxd_available(void *arg, uint16_t rxqid, uint32_t idx, int budget)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
if_softc_ctx_t scctx = sc->shared;
|
||||
struct em_rx_queue *que = &sc->rx_queues[rxqid];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
union e1000_adv_rx_desc *rxd;
|
||||
u32 staterr = 0;
|
||||
int cnt, i, iter;
|
||||
|
||||
for (iter = cnt = 0, i = idx; iter < scctx->isc_nrxd[0] && iter <= budget;) {
|
||||
rxd = (union e1000_adv_rx_desc *)&rxr->rx_base[i];
|
||||
staterr = le32toh(rxd->wb.upper.status_error);
|
||||
|
||||
if ((staterr & E1000_RXD_STAT_DD) == 0)
|
||||
break;
|
||||
|
||||
if (++i == scctx->isc_nrxd[0]) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (staterr & E1000_RXD_STAT_EOP)
|
||||
cnt++;
|
||||
iter++;
|
||||
}
|
||||
{
|
||||
struct e1000_hw *hw = &sc->hw;
|
||||
int rdt, rdh;
|
||||
rdt = E1000_READ_REG(hw, E1000_RDT(rxr->me));
|
||||
rdh = E1000_READ_REG(hw, E1000_RDH(rxr->me));
|
||||
DPRINTF(iflib_get_dev(sc->ctx), "sidx:%d eidx:%d iter=%d pktcnt=%d RDT=%d RDH=%d\n", idx, i, iter, cnt, rdt, rdh);
|
||||
}
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Routine sends data which has been dma'ed into host memory
|
||||
* to upper layer. Initialize ri structure.
|
||||
*
|
||||
* Returns 0 upon success, errno on failure
|
||||
***************************************************************/
|
||||
|
||||
static int
|
||||
igb_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
if_softc_ctx_t scctx = adapter->shared;
|
||||
struct em_rx_queue *que = &adapter->rx_queues[ri->iri_qsidx];
|
||||
struct rx_ring *rxr = &que->rxr;
|
||||
struct ifnet *ifp = iflib_get_ifp(adapter->ctx);
|
||||
union e1000_adv_rx_desc *rxd;
|
||||
|
||||
u16 pkt_info, len;
|
||||
u16 vtag = 0;
|
||||
u32 ptype;
|
||||
u32 staterr = 0;
|
||||
bool eop;
|
||||
int i = 0;
|
||||
int cidx = ri->iri_cidx;
|
||||
|
||||
do {
|
||||
rxd = (union e1000_adv_rx_desc *)&rxr->rx_base[cidx];
|
||||
staterr = le32toh(rxd->wb.upper.status_error);
|
||||
pkt_info = le16toh(rxd->wb.lower.lo_dword.hs_rss.pkt_info);
|
||||
|
||||
MPASS ((staterr & E1000_RXD_STAT_DD) != 0);
|
||||
|
||||
len = le16toh(rxd->wb.upper.length);
|
||||
ptype = le32toh(rxd->wb.lower.lo_dword.data) & IGB_PKTTYPE_MASK;
|
||||
|
||||
ri->iri_len += len;
|
||||
rxr->rx_bytes += ri->iri_len;
|
||||
|
||||
rxd->wb.upper.status_error = 0;
|
||||
eop = ((staterr & E1000_RXD_STAT_EOP) == E1000_RXD_STAT_EOP);
|
||||
|
||||
if (((adapter->hw.mac.type == e1000_i350) ||
|
||||
(adapter->hw.mac.type == e1000_i354)) &&
|
||||
(staterr & E1000_RXDEXT_STATERR_LB))
|
||||
vtag = be16toh(rxd->wb.upper.vlan);
|
||||
else
|
||||
vtag = le16toh(rxd->wb.upper.vlan);
|
||||
|
||||
/* Make sure bad packets are discarded */
|
||||
if (eop && ((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) != 0)) {
|
||||
adapter->dropped_pkts++;
|
||||
++rxr->rx_discarded;
|
||||
return (EBADMSG);
|
||||
}
|
||||
ri->iri_frags[i].irf_flid = 0;
|
||||
ri->iri_frags[i].irf_idx = cidx;
|
||||
ri->iri_frags[i].irf_len = len;
|
||||
|
||||
if (++cidx == scctx->isc_nrxd[0])
|
||||
cidx = 0;
|
||||
#ifdef notyet
|
||||
if (rxr->hdr_split == TRUE) {
|
||||
ri->iri_frags[i].irf_flid = 1;
|
||||
ri->iri_frags[i].irf_idx = cidx;
|
||||
if (++cidx == scctx->isc_nrxd[0])
|
||||
cidx = 0;
|
||||
}
|
||||
#endif
|
||||
i++;
|
||||
} while (!eop);
|
||||
|
||||
rxr->rx_packets++;
|
||||
|
||||
if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
|
||||
igb_rx_checksum(staterr, ri, ptype);
|
||||
|
||||
if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
|
||||
(staterr & E1000_RXD_STAT_VP) != 0) {
|
||||
ri->iri_vtag = vtag;
|
||||
ri->iri_flags |= M_VLANTAG;
|
||||
}
|
||||
ri->iri_flowid =
|
||||
le32toh(rxd->wb.lower.hi_dword.rss);
|
||||
ri->iri_rsstype = igb_determine_rsstype(pkt_info);
|
||||
ri->iri_nfrags = i;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Verify that the hardware indicated that the checksum is valid.
|
||||
* Inform the stack about the status of checksum so that stack
|
||||
* doesn't spend time verifying the checksum.
|
||||
*
|
||||
*********************************************************************/
|
||||
static void
|
||||
igb_rx_checksum(u32 staterr, if_rxd_info_t ri, u32 ptype)
|
||||
{
|
||||
u16 status = (u16)staterr;
|
||||
u8 errors = (u8) (staterr >> 24);
|
||||
bool sctp = FALSE;
|
||||
|
||||
/* Ignore Checksum bit is set */
|
||||
if (status & E1000_RXD_STAT_IXSM) {
|
||||
ri->iri_csum_flags = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ptype & E1000_RXDADV_PKTTYPE_ETQF) == 0 &&
|
||||
(ptype & E1000_RXDADV_PKTTYPE_SCTP) != 0)
|
||||
sctp = 1;
|
||||
else
|
||||
sctp = 0;
|
||||
|
||||
if (status & E1000_RXD_STAT_IPCS) {
|
||||
/* Did it pass? */
|
||||
if (!(errors & E1000_RXD_ERR_IPE)) {
|
||||
/* IP Checksum Good */
|
||||
ri->iri_csum_flags = CSUM_IP_CHECKED;
|
||||
ri->iri_csum_flags |= CSUM_IP_VALID;
|
||||
} else
|
||||
ri->iri_csum_flags = 0;
|
||||
}
|
||||
|
||||
if (status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) {
|
||||
u64 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
#if __FreeBSD_version >= 800000
|
||||
if (sctp) /* reassign */
|
||||
type = CSUM_SCTP_VALID;
|
||||
#endif
|
||||
/* Did it pass? */
|
||||
if (!(errors & E1000_RXD_ERR_TCPE)) {
|
||||
ri->iri_csum_flags |= type;
|
||||
if (sctp == 0)
|
||||
ri->iri_csum_data = htons(0xffff);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
*
|
||||
* Parse the packet type to determine the appropriate hash
|
||||
*
|
||||
******************************************************************/
|
||||
static int
|
||||
igb_determine_rsstype(u16 pkt_info)
|
||||
{
|
||||
switch (pkt_info & E1000_RXDADV_RSSTYPE_MASK) {
|
||||
case E1000_RXDADV_RSSTYPE_IPV4_TCP:
|
||||
return M_HASHTYPE_RSS_TCP_IPV4;
|
||||
case E1000_RXDADV_RSSTYPE_IPV4:
|
||||
return M_HASHTYPE_RSS_IPV4;
|
||||
case E1000_RXDADV_RSSTYPE_IPV6_TCP:
|
||||
return M_HASHTYPE_RSS_TCP_IPV6;
|
||||
case E1000_RXDADV_RSSTYPE_IPV6_EX:
|
||||
return M_HASHTYPE_RSS_IPV6_EX;
|
||||
case E1000_RXDADV_RSSTYPE_IPV6:
|
||||
return M_HASHTYPE_RSS_IPV6;
|
||||
case E1000_RXDADV_RSSTYPE_IPV6_TCP_EX:
|
||||
return M_HASHTYPE_RSS_TCP_IPV6_EX;
|
||||
default:
|
||||
return M_HASHTYPE_OPAQUE;
|
||||
}
|
||||
}
|
@ -235,7 +235,6 @@ device puc # Multi I/O cards and multi-channel UARTs
|
||||
device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE
|
||||
device de # DEC/Intel DC21x4x (``Tulip'')
|
||||
device em # Intel PRO/1000 Gigabit Ethernet Family
|
||||
device igb # Intel PRO/1000 PCIE Server Gigabit Family
|
||||
device ixgb # Intel PRO/10GbE Ethernet Card
|
||||
device le # AMD Am7900 LANCE and Am79C9xx PCnet
|
||||
device ti # Alteon Networks Tigon I/II gigabit Ethernet
|
||||
|
@ -195,7 +195,6 @@ device octm
|
||||
# PCI Ethernet NICs.
|
||||
device de # DEC/Intel DC21x4x (``Tulip'')
|
||||
device em # Intel PRO/1000 Gigabit Ethernet Family
|
||||
device igb # Intel PRO/1000 PCIE Server Gigabit Family
|
||||
device ix # Intel PRO/10GbE PF PCIE Ethernet Family
|
||||
device ixv # Intel PRO/10GbE VF PCIE Ethernet Family
|
||||
device le # AMD Am7900 LANCE and Am79C9xx PCnet
|
||||
|
@ -163,7 +163,6 @@ SUBDIR= \
|
||||
if_tun \
|
||||
if_vlan \
|
||||
if_vxlan \
|
||||
${_igb} \
|
||||
${_iir} \
|
||||
imgact_binmisc \
|
||||
${_intelspi} \
|
||||
@ -544,7 +543,6 @@ _cxgb= cxgb
|
||||
.if ${MACHINE_CPUARCH} == "aarch64"
|
||||
_armv8crypto= armv8crypto
|
||||
_em= em
|
||||
_igb= igb
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
|
||||
@ -572,7 +570,6 @@ _fe= fe
|
||||
_ibcore= ibcore
|
||||
.endif
|
||||
_if_ndis= if_ndis
|
||||
_igb= igb
|
||||
_io= io
|
||||
.if ${MK_OFED} != "no" || defined(ALL_MODULES)
|
||||
_ipoib= ipoib
|
||||
@ -779,7 +776,6 @@ _nvram= powermac_nvram
|
||||
_auxio= auxio
|
||||
_em= em
|
||||
_epic= epic
|
||||
_igb= igb
|
||||
.endif
|
||||
|
||||
.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH} == "armv6" || \
|
||||
|
@ -1,23 +1,28 @@
|
||||
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/e1000
|
||||
KMOD = if_em
|
||||
SRCS = device_if.h bus_if.h pci_if.h opt_ddb.h opt_em.h opt_inet.h \
|
||||
opt_inet6.h
|
||||
opt_inet6.h ifdi_if.h
|
||||
SRCS += $(CORE_SRC) $(LEGACY_SRC)
|
||||
SRCS += $(COMMON_SHARED) $(LEGACY_SHARED) $(PCIE_SHARED)
|
||||
CORE_SRC = if_em.c e1000_osdep.c
|
||||
CORE_SRC = if_em.c em_txrx.c e1000_osdep.c
|
||||
CORE_SRC += igb_txrx.c
|
||||
# This is the Legacy, pre-PCIE source, it can be
|
||||
# undefined when using modular driver if not needed
|
||||
LEGACY_SRC += if_lem.c
|
||||
COMMON_SHARED = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c \
|
||||
e1000_manage.c e1000_vf.c e1000_mbx.c e1000_i210.c
|
||||
PCIE_SHARED = e1000_80003es2lan.c e1000_ich8lan.c e1000_82571.c e1000_82575.c
|
||||
LEGACY_SHARED = e1000_82540.c e1000_82542.c e1000_82541.c e1000_82543.c
|
||||
|
||||
CFLAGS += -I${.CURDIR}/../../dev/e1000
|
||||
|
||||
CFLAGS += -I${.CURDIR}/../../../dev/e1000
|
||||
|
||||
# DEVICE_POLLING for a non-interrupt-driven method
|
||||
#CFLAGS += -DDEVICE_POLLING
|
||||
|
||||
afterinstall:
|
||||
ln -sf ${DESTDIR}${KMODDIR}/${KMOD}.ko ${DESTDIR}${KMODDIR}/if_igb.ko
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -1,24 +0,0 @@
|
||||
#$FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/e1000
|
||||
KMOD = if_igb
|
||||
SRCS = device_if.h bus_if.h pci_if.h opt_inet.h opt_inet6.h opt_rss.h
|
||||
SRCS += if_igb.c $(SHARED_SRCS)
|
||||
SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
|
||||
SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c
|
||||
SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c
|
||||
SHARED_SRCS += e1000_82575.c e1000_vf.c e1000_mbx.c e1000_i210.c
|
||||
|
||||
CFLAGS += -I${.CURDIR}/../../dev/e1000 -DSMP
|
||||
|
||||
# DEVICE_POLLING gives you non-interrupt handling
|
||||
# not advisable since MSIX gives better results
|
||||
#CFLAGS += -DDEVICE_POLLING
|
||||
|
||||
# IGB_LEGACY_TX will override the stack if_transmit path and
|
||||
# instead use the older if_start non-multiqueue capable interface.
|
||||
# This might be desirable for testing, or to enable the use of
|
||||
# ALTQ.
|
||||
#CFLAGS += -DIGB_LEGACY_TX
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -139,7 +139,6 @@ device uart_z8530
|
||||
|
||||
# Ethernet hardware
|
||||
device em # Intel PRO/1000 Gigabit Ethernet Family
|
||||
device igb # Intel PRO/1000 PCIE Server Gigabit Family
|
||||
device ix # Intel PRO/10GbE PCIE PF Ethernet Family
|
||||
device ixv # Intel PRO/10GbE PCIE VF Ethernet Family
|
||||
device glc # Sony Playstation 3 Ethernet
|
||||
|
Loading…
Reference in New Issue
Block a user