Revert "revert extended descr format for intel em(4), breaks netmap for some chipsets"

This reverts commit b0f7ff3ec8.
This commit is contained in:
Franco Fichtner 2016-10-28 16:09:29 +02:00
parent e1c1fbd711
commit 6c47ea11ac
3 changed files with 49 additions and 33 deletions

View file

@ -261,7 +261,9 @@ static bool em_rxeof(struct rx_ring *, int, int *);
#ifndef __NO_STRICT_ALIGNMENT
static int em_fixup_rx(struct rx_ring *);
#endif
static void em_receive_checksum(struct e1000_rx_desc *, struct mbuf *);
static void em_setup_rxdesc(union e1000_rx_desc_extended *,
const struct em_rxbuffer *rxbuf);
static void em_receive_checksum(uint32_t status, struct mbuf *);
static void em_transmit_checksum_setup(struct tx_ring *, struct mbuf *, int,
struct ip *, u32 *, u32 *);
static void em_tso_setup(struct tx_ring *, struct mbuf *, int, struct ip *,
@ -656,7 +658,7 @@ em_attach(device_t dev)
} else
adapter->num_tx_desc = em_txd;
if (((em_rxd * sizeof(struct e1000_rx_desc)) % EM_DBA_ALIGN) != 0 ||
if (((em_rxd * sizeof(union e1000_rx_desc_extended)) % EM_DBA_ALIGN) != 0 ||
(em_rxd > EM_MAX_RXD) || (em_rxd < EM_MIN_RXD)) {
device_printf(dev, "Using %d RX descriptors instead of %d!\n",
EM_DEFAULT_RXD, em_rxd);
@ -3491,7 +3493,7 @@ em_allocate_queues(struct adapter *adapter)
* Next the RX queues...
*/
rsize = roundup2(adapter->num_rx_desc *
sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
sizeof(union e1000_rx_desc_extended), EM_DBA_ALIGN);
for (int i = 0; i < adapter->num_queues; i++, rxconf++) {
rxr = &adapter->rx_rings[i];
rxr->adapter = adapter;
@ -3509,7 +3511,7 @@ em_allocate_queues(struct adapter *adapter)
error = ENOMEM;
goto err_rx_desc;
}
rxr->rx_base = (struct e1000_rx_desc *)rxr->rxdma.dma_vaddr;
rxr->rx_base = (union e1000_rx_desc_extended *)rxr->rxdma.dma_vaddr;
bzero((void *)rxr->rx_base, rsize);
/* Allocate receive buffers for the ring*/
@ -4297,9 +4299,10 @@ em_refresh_mbufs(struct rx_ring *rxr, int limit)
goto update;
}
rxbuf->m_head = m;
rxbuf->paddr = segs.ds_addr;
bus_dmamap_sync(rxr->rxtag,
rxbuf->map, BUS_DMASYNC_PREREAD);
rxr->rx_base[i].buffer_addr = htole64(segs.ds_addr);
em_setup_rxdesc(&rxr->rx_base[i], rxbuf);
cleaned = TRUE;
i = j; /* Next is precalulated for us */
@ -4402,7 +4405,7 @@ em_setup_receive_ring(struct rx_ring *rxr)
/* Clear the ring contents */
EM_RX_LOCK(rxr);
rsize = roundup2(adapter->num_rx_desc *
sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
sizeof(union e1000_rx_desc_extended), EM_DBA_ALIGN);
bzero((void *)rxr->rx_base, rsize);
#ifdef DEV_NETMAP
slot = netmap_reset(na, NR_RX, 0, 0);
@ -4433,8 +4436,8 @@ em_setup_receive_ring(struct rx_ring *rxr)
addr = PNMB(na, slot + si, &paddr);
netmap_load_map(na, rxr->rxtag, rxbuf->map, addr);
/* Update descriptor */
rxr->rx_base[j].buffer_addr = htole64(paddr);
rxbuf->paddr = paddr;
em_setup_rxdesc(&rxr->rx_base[j], rxbuf);
continue;
}
#endif /* DEV_NETMAP */
@ -4460,8 +4463,8 @@ em_setup_receive_ring(struct rx_ring *rxr)
bus_dmamap_sync(rxr->rxtag,
rxbuf->map, BUS_DMASYNC_PREREAD);
/* Update descriptor */
rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr);
rxbuf->paddr = seg[0].ds_addr;
em_setup_rxdesc(&rxr->rx_base[j], rxbuf);
}
rxr->next_to_check = 0;
rxr->next_to_refresh = 0;
@ -4635,7 +4638,7 @@ em_initialize_receive_unit(struct adapter *adapter)
/* Use extended rx descriptor formats */
rfctl = E1000_READ_REG(hw, E1000_RFCTL);
rfctl |= E1000_RFCTL_EXTEN;
/*
** When using MSIX interrupts we need to throttle
** using the EITR register (82574 only)
@ -4720,7 +4723,7 @@ em_initialize_receive_unit(struct adapter *adapter)
u32 rdt = adapter->num_rx_desc - 1; /* default */
E1000_WRITE_REG(hw, E1000_RDLEN(i),
adapter->num_rx_desc * sizeof(struct e1000_rx_desc));
adapter->num_rx_desc * sizeof(union e1000_rx_desc_extended));
E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32));
E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr);
/* Setup the Head and Tail Descriptor Pointers */
@ -4808,7 +4811,7 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
u16 len;
int i, processed, rxdone = 0;
bool eop;
struct e1000_rx_desc *cur;
union e1000_rx_desc_extended *cur;
EM_RX_LOCK(rxr);
@ -4829,13 +4832,13 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
break;
cur = &rxr->rx_base[i];
status = cur->status;
status = le32toh(cur->wb.upper.status_error);
mp = sendmp = NULL;
if ((status & E1000_RXD_STAT_DD) == 0)
break;
len = le16toh(cur->length);
len = le16toh(cur->wb.upper.length);
eop = (status & E1000_RXD_STAT_EOP) != 0;
if ((status & E1000_RXDEXT_ERR_FRAME_ERR_MASK) ||
@ -4875,7 +4878,7 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
sendmp = rxr->fmp;
sendmp->m_pkthdr.rcvif = ifp;
ifp->if_ipackets++;
em_receive_checksum(cur, sendmp);
em_receive_checksum(status, sendmp);
#ifndef __NO_STRICT_ALIGNMENT
if (adapter->hw.mac.max_frame_size >
(MCLBYTES - ETHER_ALIGN) &&
@ -4884,7 +4887,7 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
#endif
if (status & E1000_RXD_STAT_VP) {
sendmp->m_pkthdr.ether_vtag =
le16toh(cur->special);
le16toh(cur->wb.upper.vlan);
sendmp->m_flags |= M_VLANTAG;
}
#ifndef __NO_STRICT_ALIGNMENT
@ -4898,7 +4901,7 @@ next_desc:
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/* Zero out the receive descriptors status. */
cur->status = 0;
cur->wb.upper.status_error &= htole32(~0xFF);
++rxdone; /* cumulative for POLL */
++processed;
@ -5009,6 +5012,14 @@ em_fixup_rx(struct rx_ring *rxr)
}
#endif
static void
em_setup_rxdesc(union e1000_rx_desc_extended *rxd, const struct em_rxbuffer *rxbuf)
{
rxd->read.buffer_addr = htole64(rxbuf->paddr);
/* DD bits must be cleared */
rxd->wb.upper.status_error= 0;
}
/*********************************************************************
*
* Verify that the hardware indicated that the checksum is valid.
@ -5017,23 +5028,27 @@ em_fixup_rx(struct rx_ring *rxr)
*
*********************************************************************/
static void
em_receive_checksum(struct e1000_rx_desc *rx_desc, struct mbuf *mp)
em_receive_checksum(uint32_t status, struct mbuf *mp)
{
mp->m_pkthdr.csum_flags = 0;
/* Ignore Checksum bit is set */
if (rx_desc->status & E1000_RXD_STAT_IXSM)
if (status & E1000_RXD_STAT_IXSM)
return;
if (rx_desc->errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE))
return;
/* IP Checksum Good? */
if (rx_desc->status & E1000_RXD_STAT_IPCS)
/* 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) {
mp->m_pkthdr.csum_flags = (CSUM_IP_CHECKED | CSUM_IP_VALID);
}
/* TCP or UDP checksum */
if (rx_desc->status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) {
if ((status & (E1000_RXD_STAT_TCPCS | E1000_RXDEXT_STATERR_TCPE)) ==
E1000_RXD_STAT_TCPCS) {
mp->m_pkthdr.csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
mp->m_pkthdr.csum_data = htons(0xffff);
}
if (status & E1000_RXD_STAT_UDPCS) {
mp->m_pkthdr.csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
mp->m_pkthdr.csum_data = htons(0xffff);
}

View file

@ -365,7 +365,7 @@ struct rx_ring {
u32 payload;
struct task rx_task;
struct taskqueue *tq;
struct e1000_rx_desc *rx_base;
union e1000_rx_desc_extended *rx_base;
struct em_dma_alloc rxdma;
u32 next_to_refresh;
u32 next_to_check;
@ -511,6 +511,7 @@ 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;
};

View file

@ -241,12 +241,12 @@ em_netmap_rxsync(struct netmap_kring *kring, int flags)
nm_i = netmap_idx_n2k(kring, nic_i);
for (n = 0; ; n++) { // XXX no need to count
struct e1000_rx_desc *curr = &rxr->rx_base[nic_i];
uint32_t staterr = le32toh(curr->status);
union e1000_rx_desc_extended *curr = &rxr->rx_base[nic_i];
uint32_t staterr = le32toh(curr->wb.upper.status_error);
if ((staterr & E1000_RXD_STAT_DD) == 0)
break;
ring->slot[nm_i].len = le16toh(curr->length);
ring->slot[nm_i].len = le16toh(curr->wb.upper.length);
ring->slot[nm_i].flags = slot_flags;
bus_dmamap_sync(rxr->rxtag, rxr->rx_buffers[nic_i].map,
BUS_DMASYNC_POSTREAD);
@ -273,7 +273,7 @@ em_netmap_rxsync(struct netmap_kring *kring, int flags)
uint64_t paddr;
void *addr = PNMB(na, slot, &paddr);
struct e1000_rx_desc *curr = &rxr->rx_base[nic_i];
union e1000_rx_desc_extended *curr = &rxr->rx_base[nic_i];
struct em_rxbuffer *rxbuf = &rxr->rx_buffers[nic_i];
if (addr == NETMAP_BUF_BASE(na)) /* bad buf */
@ -281,11 +281,11 @@ em_netmap_rxsync(struct netmap_kring *kring, int flags)
if (slot->flags & NS_BUF_CHANGED) {
/* buffer has changed, reload map */
curr->buffer_addr = htole64(paddr);
curr->read.buffer_addr = htole64(paddr);
netmap_reload_map(na, rxr->rxtag, rxbuf->map, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
curr->status = 0;
curr->wb.upper.status_error = 0;
bus_dmamap_sync(rxr->rxtag, rxbuf->map,
BUS_DMASYNC_PREREAD);
nm_i = nm_next(nm_i, lim);