- Bus DMA'fy the driver
- Use htole* macros where appropriate so that the driver could work on non-x86 architectures - Use m_getcl() instead of MGETHDR/MCLGET macros Submitted by: sam (Sam Leffler)
This commit is contained in:
parent
6b35b9cda0
commit
1163149bb1
@ -155,6 +155,9 @@ static int em_82547_fifo_workaround(struct adapter *, int);
|
|||||||
static void em_82547_update_fifo_head(struct adapter *, int);
|
static void em_82547_update_fifo_head(struct adapter *, int);
|
||||||
static int em_82547_tx_fifo_reset(struct adapter *);
|
static int em_82547_tx_fifo_reset(struct adapter *);
|
||||||
static void em_82547_move_tail(void *arg);
|
static void em_82547_move_tail(void *arg);
|
||||||
|
static int em_dma_malloc(struct adapter *, bus_size_t,
|
||||||
|
struct em_dma_alloc *, int);
|
||||||
|
static void em_dma_free(struct adapter *, struct em_dma_alloc *);
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* FreeBSD Device Interface Entry Points
|
* FreeBSD Device Interface Entry Points
|
||||||
@ -329,36 +332,36 @@ em_attach(device_t dev)
|
|||||||
sizeof(struct em_tx_desc), 4096);
|
sizeof(struct em_tx_desc), 4096);
|
||||||
|
|
||||||
/* Allocate Transmit Descriptor ring */
|
/* Allocate Transmit Descriptor ring */
|
||||||
if (!(adapter->tx_desc_base = (struct em_tx_desc *)
|
if (em_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
|
||||||
contigmalloc(tsize, M_DEVBUF, M_NOWAIT, 0, ~0, PAGE_SIZE, 0))) {
|
printf("em%d: Unable to allocate tx_desc memory\n",
|
||||||
printf("em%d: Unable to allocate TxDescriptor memory\n",
|
adapter->unit);
|
||||||
adapter->unit);
|
em_free_pci_resources(adapter);
|
||||||
em_free_pci_resources(adapter);
|
splx(s);
|
||||||
splx(s);
|
return(ENOMEM);
|
||||||
return(ENOMEM);
|
}
|
||||||
}
|
adapter->tx_desc_base = (struct em_tx_desc *) adapter->txdma.dma_vaddr;
|
||||||
|
|
||||||
rsize = EM_ROUNDUP(adapter->num_rx_desc *
|
rsize = EM_ROUNDUP(adapter->num_rx_desc *
|
||||||
sizeof(struct em_rx_desc), 4096);
|
sizeof(struct em_rx_desc), 4096);
|
||||||
|
|
||||||
/* Allocate Receive Descriptor ring */
|
/* Allocate Receive Descriptor ring */
|
||||||
if (!(adapter->rx_desc_base = (struct em_rx_desc *)
|
if (em_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
|
||||||
contigmalloc(rsize, M_DEVBUF, M_NOWAIT, 0, ~0, PAGE_SIZE, 0))) {
|
printf("em%d: Unable to allocate rx_desc memory\n",
|
||||||
printf("em%d: Unable to allocate rx_desc memory\n",
|
adapter->unit);
|
||||||
adapter->unit);
|
em_free_pci_resources(adapter);
|
||||||
em_free_pci_resources(adapter);
|
em_dma_free(adapter, &adapter->txdma);
|
||||||
contigfree(adapter->tx_desc_base, tsize, M_DEVBUF);
|
splx(s);
|
||||||
splx(s);
|
return(ENOMEM);
|
||||||
return(ENOMEM);
|
}
|
||||||
}
|
adapter->rx_desc_base = (struct em_rx_desc *) adapter->rxdma.dma_vaddr;
|
||||||
|
|
||||||
/* Initialize the hardware */
|
/* Initialize the hardware */
|
||||||
if (em_hardware_init(adapter)) {
|
if (em_hardware_init(adapter)) {
|
||||||
printf("em%d: Unable to initialize the hardware\n",
|
printf("em%d: Unable to initialize the hardware\n",
|
||||||
adapter->unit);
|
adapter->unit);
|
||||||
em_free_pci_resources(adapter);
|
em_free_pci_resources(adapter);
|
||||||
contigfree(adapter->tx_desc_base, tsize, M_DEVBUF);
|
em_dma_free(adapter, &adapter->txdma);
|
||||||
contigfree(adapter->rx_desc_base, rsize, M_DEVBUF);
|
em_dma_free(adapter, &adapter->rxdma);
|
||||||
splx(s);
|
splx(s);
|
||||||
return(EIO);
|
return(EIO);
|
||||||
}
|
}
|
||||||
@ -368,8 +371,8 @@ em_attach(device_t dev)
|
|||||||
printf("em%d: EEPROM read error while reading mac address\n",
|
printf("em%d: EEPROM read error while reading mac address\n",
|
||||||
adapter->unit);
|
adapter->unit);
|
||||||
em_free_pci_resources(adapter);
|
em_free_pci_resources(adapter);
|
||||||
contigfree(adapter->tx_desc_base, tsize, M_DEVBUF);
|
em_dma_free(adapter, &adapter->txdma);
|
||||||
contigfree(adapter->rx_desc_base, rsize, M_DEVBUF);
|
em_dma_free(adapter, &adapter->rxdma);
|
||||||
splx(s);
|
splx(s);
|
||||||
return(EIO);
|
return(EIO);
|
||||||
}
|
}
|
||||||
@ -418,7 +421,6 @@ em_detach(device_t dev)
|
|||||||
struct adapter * adapter = device_get_softc(dev);
|
struct adapter * adapter = device_get_softc(dev);
|
||||||
struct ifnet *ifp = &adapter->interface_data.ac_if;
|
struct ifnet *ifp = &adapter->interface_data.ac_if;
|
||||||
int s;
|
int s;
|
||||||
int size;
|
|
||||||
|
|
||||||
INIT_DEBUGOUT("em_detach: begin");
|
INIT_DEBUGOUT("em_detach: begin");
|
||||||
s = splimp();
|
s = splimp();
|
||||||
@ -431,24 +433,18 @@ em_detach(device_t dev)
|
|||||||
ether_ifdetach(&adapter->interface_data.ac_if);
|
ether_ifdetach(&adapter->interface_data.ac_if);
|
||||||
#endif
|
#endif
|
||||||
em_free_pci_resources(adapter);
|
em_free_pci_resources(adapter);
|
||||||
|
|
||||||
size = EM_ROUNDUP(adapter->num_tx_desc *
|
|
||||||
sizeof(struct em_tx_desc), 4096);
|
|
||||||
|
|
||||||
/* Free Transmit Descriptor ring */
|
/* Free Transmit Descriptor ring */
|
||||||
if (adapter->tx_desc_base) {
|
if (adapter->tx_desc_base) {
|
||||||
contigfree(adapter->tx_desc_base, size, M_DEVBUF);
|
em_dma_free(adapter, &adapter->txdma);
|
||||||
adapter->tx_desc_base = NULL;
|
adapter->tx_desc_base = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = EM_ROUNDUP(adapter->num_rx_desc *
|
/* Free Receive Descriptor ring */
|
||||||
sizeof(struct em_rx_desc), 4096);
|
if (adapter->rx_desc_base) {
|
||||||
|
em_dma_free(adapter, &adapter->rxdma);
|
||||||
/* Free Receive Descriptor ring */
|
adapter->rx_desc_base = NULL;
|
||||||
if (adapter->rx_desc_base) {
|
}
|
||||||
contigfree(adapter->rx_desc_base, size, M_DEVBUF);
|
|
||||||
adapter->rx_desc_base = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove from the adapter list */
|
/* Remove from the adapter list */
|
||||||
if (em_adapter_list == adapter)
|
if (em_adapter_list == adapter)
|
||||||
@ -947,6 +943,19 @@ em_media_change(struct ifnet *ifp)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
em_tx_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, int error)
|
||||||
|
{
|
||||||
|
struct em_q *q = arg;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
return;
|
||||||
|
KASSERT(nsegs <= EM_MAX_SCATTER,
|
||||||
|
("Too many DMA segments returned when mapping tx packet"));
|
||||||
|
q->nsegs = nsegs;
|
||||||
|
bcopy(seg, q->segs, nsegs * sizeof(seg[0]));
|
||||||
|
}
|
||||||
|
|
||||||
#define EM_FIFO_HDR 0x10
|
#define EM_FIFO_HDR 0x10
|
||||||
#define EM_82547_PKT_THRESH 0x3e0
|
#define EM_82547_PKT_THRESH 0x3e0
|
||||||
#define EM_82547_TX_FIFO_SIZE 0x2800
|
#define EM_82547_TX_FIFO_SIZE 0x2800
|
||||||
@ -957,43 +966,63 @@ em_media_change(struct ifnet *ifp)
|
|||||||
*
|
*
|
||||||
* return 0 on success, positive on failure
|
* return 0 on success, positive on failure
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
static int
|
||||||
static int
|
|
||||||
em_encap(struct adapter *adapter, struct mbuf *m_head)
|
em_encap(struct adapter *adapter, struct mbuf *m_head)
|
||||||
{
|
{
|
||||||
vm_offset_t virtual_addr;
|
|
||||||
u_int32_t txd_upper;
|
u_int32_t txd_upper;
|
||||||
u_int32_t txd_lower;
|
u_int32_t txd_lower;
|
||||||
int txd_used, i, txd_saved;
|
int i, j, error;
|
||||||
struct mbuf *mp;
|
|
||||||
|
|
||||||
#if __FreeBSD_version < 500000
|
#if __FreeBSD_version < 500000
|
||||||
struct ifvlan *ifv = NULL;
|
struct ifvlan *ifv = NULL;
|
||||||
#else
|
#else
|
||||||
struct m_tag *mtag;
|
struct m_tag *mtag;
|
||||||
#endif
|
#endif
|
||||||
|
struct em_q q;
|
||||||
struct em_buffer *tx_buffer = NULL;
|
struct em_buffer *tx_buffer = NULL;
|
||||||
struct em_tx_desc *current_tx_desc = NULL;
|
struct em_tx_desc *current_tx_desc = NULL;
|
||||||
struct ifnet *ifp = &adapter->interface_data.ac_if;
|
struct ifnet *ifp = &adapter->interface_data.ac_if;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force a cleanup if number of TX descriptors
|
* Force a cleanup if number of TX descriptors
|
||||||
* available hits the threshold
|
* available hits the threshold
|
||||||
*/
|
*/
|
||||||
if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD)
|
if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
|
||||||
em_clean_transmit_interrupts(adapter);
|
em_clean_transmit_interrupts(adapter);
|
||||||
|
if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
|
||||||
|
adapter->no_tx_desc_avail1++;
|
||||||
|
return(ENOBUFS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
|
/*
|
||||||
adapter->no_tx_desc_avail1++;
|
* Map the packet for DMA.
|
||||||
return (ENOBUFS);
|
*/
|
||||||
}
|
if (bus_dmamap_create(adapter->txtag, BUS_DMA_NOWAIT, &q.map)) {
|
||||||
|
adapter->no_tx_map_avail++;
|
||||||
|
return (ENOMEM);
|
||||||
|
}
|
||||||
|
error = bus_dmamap_load_mbuf(adapter->txtag, q.map,
|
||||||
|
m_head, em_tx_cb, &q, BUS_DMA_NOWAIT);
|
||||||
|
if (error != 0) {
|
||||||
|
adapter->no_tx_dma_setup++;
|
||||||
|
bus_dmamap_destroy(adapter->txtag, q.map);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
KASSERT(q.nsegs != 0, ("em_encap: empty packet"));
|
||||||
|
|
||||||
if (ifp->if_hwassist > 0) {
|
if (q.nsegs > adapter->num_tx_desc_avail) {
|
||||||
em_transmit_checksum_setup(adapter, m_head,
|
adapter->no_tx_desc_avail2++;
|
||||||
&txd_upper, &txd_lower);
|
bus_dmamap_destroy(adapter->txtag, q.map);
|
||||||
}
|
return (ENOBUFS);
|
||||||
else
|
}
|
||||||
txd_upper = txd_lower = 0;
|
|
||||||
|
|
||||||
|
if (ifp->if_hwassist > 0) {
|
||||||
|
em_transmit_checksum_setup(adapter, m_head,
|
||||||
|
&txd_upper, &txd_lower);
|
||||||
|
} else
|
||||||
|
txd_upper = txd_lower = 0;
|
||||||
|
|
||||||
|
|
||||||
/* Find out if we are in vlan mode */
|
/* Find out if we are in vlan mode */
|
||||||
@ -1003,80 +1032,68 @@ em_encap(struct adapter *adapter, struct mbuf *m_head)
|
|||||||
m_head->m_pkthdr.rcvif->if_type == IFT_L2VLAN)
|
m_head->m_pkthdr.rcvif->if_type == IFT_L2VLAN)
|
||||||
ifv = m_head->m_pkthdr.rcvif->if_softc;
|
ifv = m_head->m_pkthdr.rcvif->if_softc;
|
||||||
#else
|
#else
|
||||||
mtag = VLAN_OUTPUT_TAG(ifp, m_head);
|
mtag = VLAN_OUTPUT_TAG(ifp, m_head);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i = adapter->next_avail_tx_desc;
|
i = adapter->next_avail_tx_desc;
|
||||||
txd_saved = i;
|
for (j = 0; j < q.nsegs; j++) {
|
||||||
txd_used = 0;
|
tx_buffer = &adapter->tx_buffer_area[i];
|
||||||
for (mp = m_head; mp != NULL; mp = mp->m_next) {
|
current_tx_desc = &adapter->tx_desc_base[i];
|
||||||
if (mp->m_len == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (txd_used == adapter->num_tx_desc_avail) {
|
current_tx_desc->buffer_addr = htole64(q.segs[j].ds_addr);
|
||||||
adapter->next_avail_tx_desc = txd_saved;
|
current_tx_desc->lower.data = htole32(
|
||||||
adapter->no_tx_desc_avail2++;
|
adapter->txd_cmd | txd_lower | q.segs[j].ds_len);
|
||||||
return (ENOBUFS);
|
current_tx_desc->upper.data = htole32(txd_upper);
|
||||||
}
|
|
||||||
|
|
||||||
tx_buffer = &adapter->tx_buffer_area[i];
|
if (++i == adapter->num_tx_desc)
|
||||||
current_tx_desc = &adapter->tx_desc_base[i];
|
i = 0;
|
||||||
virtual_addr = mtod(mp, vm_offset_t);
|
|
||||||
current_tx_desc->buffer_addr = vtophys(virtual_addr);
|
|
||||||
|
|
||||||
current_tx_desc->lower.data = (adapter->txd_cmd | txd_lower | mp->m_len);
|
tx_buffer->m_head = NULL;
|
||||||
current_tx_desc->upper.data = (txd_upper);
|
}
|
||||||
|
|
||||||
if (++i == adapter->num_tx_desc)
|
adapter->num_tx_desc_avail -= q.nsegs;
|
||||||
i = 0;
|
adapter->next_avail_tx_desc = i;
|
||||||
|
|
||||||
tx_buffer->m_head = NULL;
|
|
||||||
|
|
||||||
txd_used++;
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter->num_tx_desc_avail -= txd_used;
|
|
||||||
adapter->next_avail_tx_desc = i;
|
|
||||||
|
|
||||||
#if __FreeBSD_version < 500000
|
#if __FreeBSD_version < 500000
|
||||||
if (ifv != NULL) {
|
if (ifv != NULL) {
|
||||||
/* Set the vlan id */
|
/* Set the vlan id */
|
||||||
current_tx_desc->upper.fields.special = ifv->ifv_tag;
|
current_tx_desc->upper.fields.special = htole16(ifv->ifv_tag);
|
||||||
#else
|
#else
|
||||||
if (mtag != NULL) {
|
if (mtag != NULL) {
|
||||||
/* Set the vlan id */
|
/* Set the vlan id */
|
||||||
current_tx_desc->upper.fields.special = VLAN_TAG_VALUE(mtag);
|
current_tx_desc->upper.fields.special = htole16(VLAN_TAG_VALUE(mtag));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Tell hardware to add tag */
|
/* Tell hardware to add tag */
|
||||||
current_tx_desc->lower.data |= E1000_TXD_CMD_VLE;
|
current_tx_desc->lower.data |= htole32(E1000_TXD_CMD_VLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_buffer->m_head = m_head;
|
tx_buffer->m_head = m_head;
|
||||||
|
tx_buffer->map = q.map;
|
||||||
/*
|
bus_dmamap_sync(adapter->txtag, q.map, BUS_DMASYNC_PREWRITE);
|
||||||
* Last Descriptor of Packet needs End Of Packet (EOP)
|
|
||||||
*/
|
|
||||||
current_tx_desc->lower.data |= (E1000_TXD_CMD_EOP);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Advance the Transmit Descriptor Tail (Tdt), this tells the E1000
|
* Last Descriptor of Packet needs End Of Packet (EOP)
|
||||||
* that this frame is available to transmit.
|
*/
|
||||||
*/
|
current_tx_desc->lower.data |= htole32(E1000_TXD_CMD_EOP);
|
||||||
if (adapter->hw.mac_type == em_82547 &&
|
|
||||||
adapter->link_duplex == HALF_DUPLEX) {
|
|
||||||
em_82547_move_tail(adapter);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
E1000_WRITE_REG(&adapter->hw, TDT, i);
|
|
||||||
if (adapter->hw.mac_type == em_82547) {
|
|
||||||
em_82547_update_fifo_head(adapter, m_head->m_pkthdr.len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
/*
|
||||||
|
* Advance the Transmit Descriptor Tail (Tdt), this tells the E1000
|
||||||
|
* that this frame is available to transmit.
|
||||||
|
*/
|
||||||
|
if (adapter->hw.mac_type == em_82547 &&
|
||||||
|
adapter->link_duplex == HALF_DUPLEX) {
|
||||||
|
em_82547_move_tail(adapter);
|
||||||
|
} else {
|
||||||
|
E1000_WRITE_REG(&adapter->hw, TDT, i);
|
||||||
|
if (adapter->hw.mac_type == em_82547) {
|
||||||
|
em_82547_update_fifo_head(adapter, m_head->m_pkthdr.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* 82547 workaround to avoid controller hang in half-duplex environment.
|
* 82547 workaround to avoid controller hang in half-duplex environment.
|
||||||
@ -1715,6 +1732,92 @@ em_smartspeed(struct adapter *adapter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manage DMA'able memory.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
em_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
return;
|
||||||
|
*(bus_addr_t*) arg = segs->ds_addr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
em_dma_malloc(struct adapter *adapter, bus_size_t size,
|
||||||
|
struct em_dma_alloc *dma, int mapflags)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = bus_dma_tag_create(NULL, /* parent */
|
||||||
|
PAGE_SIZE, 0, /* alignment, bounds */
|
||||||
|
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||||
|
BUS_SPACE_MAXADDR, /* highaddr */
|
||||||
|
NULL, NULL, /* filter, filterarg */
|
||||||
|
size, /* maxsize */
|
||||||
|
1, /* nsegments */
|
||||||
|
size, /* maxsegsize */
|
||||||
|
BUS_DMA_ALLOCNOW, /* flags */
|
||||||
|
&dma->dma_tag);
|
||||||
|
if (r != 0) {
|
||||||
|
printf("em%d: em_dma_malloc: bus_dma_tag_create failed; "
|
||||||
|
"error %u\n", adapter->unit, r);
|
||||||
|
goto fail_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = bus_dmamap_create(dma->dma_tag, BUS_DMA_NOWAIT, &dma->dma_map);
|
||||||
|
if (r != 0) {
|
||||||
|
printf("em%d: em_dma_malloc: bus_dmamap_create failed; "
|
||||||
|
"error %u\n", adapter->unit, r);
|
||||||
|
goto fail_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr,
|
||||||
|
BUS_DMA_NOWAIT, &dma->dma_map);
|
||||||
|
if (r != 0) {
|
||||||
|
printf("em%d: em_dma_malloc: bus_dmammem_alloc failed; "
|
||||||
|
"size %u, error %u\n", adapter->unit, size, r);
|
||||||
|
goto fail_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
|
||||||
|
size,
|
||||||
|
em_dmamap_cb,
|
||||||
|
&dma->dma_paddr,
|
||||||
|
mapflags | BUS_DMA_NOWAIT);
|
||||||
|
if (r != 0) {
|
||||||
|
printf("em%d: em_dma_malloc: bus_dmamap_load failed; "
|
||||||
|
"error %u\n", adapter->unit, r);
|
||||||
|
goto fail_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
dma->dma_size = size;
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
fail_3:
|
||||||
|
bus_dmamap_unload(dma->dma_tag, dma->dma_map);
|
||||||
|
fail_2:
|
||||||
|
bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
|
||||||
|
fail_1:
|
||||||
|
bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
|
||||||
|
bus_dma_tag_destroy(dma->dma_tag);
|
||||||
|
fail_0:
|
||||||
|
dma->dma_map = NULL;
|
||||||
|
dma->dma_tag = NULL;
|
||||||
|
return (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
em_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
|
||||||
|
{
|
||||||
|
bus_dmamap_unload(dma->dma_tag, dma->dma_map);
|
||||||
|
bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
|
||||||
|
bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
|
||||||
|
bus_dma_tag_destroy(dma->dma_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Allocate memory for tx_buffer structures. The tx_buffer stores all
|
* Allocate memory for tx_buffer structures. The tx_buffer stores all
|
||||||
@ -1747,22 +1850,39 @@ em_allocate_transmit_structures(struct adapter * adapter)
|
|||||||
static int
|
static int
|
||||||
em_setup_transmit_structures(struct adapter * adapter)
|
em_setup_transmit_structures(struct adapter * adapter)
|
||||||
{
|
{
|
||||||
if (em_allocate_transmit_structures(adapter))
|
/*
|
||||||
return ENOMEM;
|
* Setup DMA descriptor areas.
|
||||||
|
*/
|
||||||
|
if (bus_dma_tag_create(NULL, /* parent */
|
||||||
|
PAGE_SIZE, 0, /* alignment, bounds */
|
||||||
|
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||||
|
BUS_SPACE_MAXADDR, /* highaddr */
|
||||||
|
NULL, NULL, /* filter, filterarg */
|
||||||
|
MCLBYTES * 8, /* maxsize */
|
||||||
|
EM_MAX_SCATTER, /* nsegments */
|
||||||
|
MCLBYTES * 8, /* maxsegsize */
|
||||||
|
BUS_DMA_ALLOCNOW, /* flags */
|
||||||
|
&adapter->txtag)) {
|
||||||
|
printf("em%d: Unable to allocate TX DMA tag\n", adapter->unit);
|
||||||
|
return (ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (em_allocate_transmit_structures(adapter))
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
bzero((void *) adapter->tx_desc_base,
|
bzero((void *) adapter->tx_desc_base,
|
||||||
(sizeof(struct em_tx_desc)) * adapter->num_tx_desc);
|
(sizeof(struct em_tx_desc)) * adapter->num_tx_desc);
|
||||||
|
|
||||||
adapter->next_avail_tx_desc = 0;
|
adapter->next_avail_tx_desc = 0;
|
||||||
adapter->oldest_used_tx_desc = 0;
|
adapter->oldest_used_tx_desc = 0;
|
||||||
|
|
||||||
/* Set number of descriptors available */
|
/* Set number of descriptors available */
|
||||||
adapter->num_tx_desc_avail = adapter->num_tx_desc;
|
adapter->num_tx_desc_avail = adapter->num_tx_desc;
|
||||||
|
|
||||||
/* Set checksum context */
|
/* Set checksum context */
|
||||||
adapter->active_checksum_context = OFFLOAD_NONE;
|
adapter->active_checksum_context = OFFLOAD_NONE;
|
||||||
|
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
@ -1851,24 +1971,31 @@ em_initialize_transmit_unit(struct adapter * adapter)
|
|||||||
static void
|
static void
|
||||||
em_free_transmit_structures(struct adapter * adapter)
|
em_free_transmit_structures(struct adapter * adapter)
|
||||||
{
|
{
|
||||||
struct em_buffer *tx_buffer;
|
struct em_buffer *tx_buffer;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
INIT_DEBUGOUT("free_transmit_structures: begin");
|
INIT_DEBUGOUT("free_transmit_structures: begin");
|
||||||
|
|
||||||
if (adapter->tx_buffer_area != NULL) {
|
if (adapter->tx_buffer_area != NULL) {
|
||||||
tx_buffer = adapter->tx_buffer_area;
|
tx_buffer = adapter->tx_buffer_area;
|
||||||
for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
|
for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
|
||||||
if (tx_buffer->m_head != NULL)
|
if (tx_buffer->m_head != NULL) {
|
||||||
m_freem(tx_buffer->m_head);
|
bus_dmamap_unload(adapter->txtag, tx_buffer->map);
|
||||||
tx_buffer->m_head = NULL;
|
bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
|
||||||
}
|
m_freem(tx_buffer->m_head);
|
||||||
}
|
}
|
||||||
if (adapter->tx_buffer_area != NULL) {
|
tx_buffer->m_head = NULL;
|
||||||
free(adapter->tx_buffer_area, M_DEVBUF);
|
}
|
||||||
adapter->tx_buffer_area = NULL;
|
}
|
||||||
}
|
if (adapter->tx_buffer_area != NULL) {
|
||||||
return;
|
free(adapter->tx_buffer_area, M_DEVBUF);
|
||||||
|
adapter->tx_buffer_area = NULL;
|
||||||
|
}
|
||||||
|
if (adapter->txtag != NULL) {
|
||||||
|
bus_dma_tag_destroy(adapter->txtag);
|
||||||
|
adapter->txtag = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
@ -1927,11 +2054,11 @@ em_transmit_checksum_setup(struct adapter * adapter,
|
|||||||
TXD->lower_setup.ip_fields.ipcso =
|
TXD->lower_setup.ip_fields.ipcso =
|
||||||
ETHER_HDR_LEN + offsetof(struct ip, ip_sum);
|
ETHER_HDR_LEN + offsetof(struct ip, ip_sum);
|
||||||
TXD->lower_setup.ip_fields.ipcse =
|
TXD->lower_setup.ip_fields.ipcse =
|
||||||
ETHER_HDR_LEN + sizeof(struct ip) - 1;
|
htole16(ETHER_HDR_LEN + sizeof(struct ip) - 1);
|
||||||
|
|
||||||
TXD->upper_setup.tcp_fields.tucss =
|
TXD->upper_setup.tcp_fields.tucss =
|
||||||
ETHER_HDR_LEN + sizeof(struct ip);
|
ETHER_HDR_LEN + sizeof(struct ip);
|
||||||
TXD->upper_setup.tcp_fields.tucse = 0;
|
TXD->upper_setup.tcp_fields.tucse = htole16(0);
|
||||||
|
|
||||||
if (adapter->active_checksum_context == OFFLOAD_TCP_IP) {
|
if (adapter->active_checksum_context == OFFLOAD_TCP_IP) {
|
||||||
TXD->upper_setup.tcp_fields.tucso =
|
TXD->upper_setup.tcp_fields.tucso =
|
||||||
@ -1943,8 +2070,8 @@ em_transmit_checksum_setup(struct adapter * adapter,
|
|||||||
offsetof(struct udphdr, uh_sum);
|
offsetof(struct udphdr, uh_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
TXD->tcp_seg_setup.data = 0;
|
TXD->tcp_seg_setup.data = htole32(0);
|
||||||
TXD->cmd_and_length = (adapter->txd_cmd | E1000_TXD_CMD_DEXT);
|
TXD->cmd_and_length = htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT);
|
||||||
|
|
||||||
tx_buffer->m_head = NULL;
|
tx_buffer->m_head = NULL;
|
||||||
|
|
||||||
@ -1969,8 +2096,8 @@ em_clean_transmit_interrupts(struct adapter * adapter)
|
|||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
int i, num_avail;
|
int i, num_avail;
|
||||||
struct em_buffer *tx_buffer;
|
struct em_buffer *tx_buffer;
|
||||||
struct em_tx_desc *tx_desc;
|
struct em_tx_desc *tx_desc;
|
||||||
|
|
||||||
if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
|
if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
|
||||||
return;
|
return;
|
||||||
@ -1979,30 +2106,37 @@ em_clean_transmit_interrupts(struct adapter * adapter)
|
|||||||
#ifdef DBG_STATS
|
#ifdef DBG_STATS
|
||||||
adapter->clean_tx_interrupts++;
|
adapter->clean_tx_interrupts++;
|
||||||
#endif
|
#endif
|
||||||
num_avail = adapter->num_tx_desc_avail;
|
num_avail = adapter->num_tx_desc_avail;
|
||||||
i = adapter->oldest_used_tx_desc;
|
i = adapter->oldest_used_tx_desc;
|
||||||
|
|
||||||
tx_buffer = &adapter->tx_buffer_area[i];
|
tx_buffer = &adapter->tx_buffer_area[i];
|
||||||
tx_desc = &adapter->tx_desc_base[i];
|
tx_desc = &adapter->tx_desc_base[i];
|
||||||
|
|
||||||
while(tx_desc->upper.fields.status & E1000_TXD_STAT_DD) {
|
while (tx_desc->upper.fields.status & E1000_TXD_STAT_DD) {
|
||||||
|
|
||||||
|
tx_desc->upper.data = 0;
|
||||||
|
num_avail++;
|
||||||
|
|
||||||
|
if (tx_buffer->m_head) {
|
||||||
|
|
||||||
|
bus_dmamap_sync(adapter->txtag, tx_buffer->map,
|
||||||
|
BUS_DMASYNC_POSTWRITE);
|
||||||
|
bus_dmamap_unload(adapter->txtag, tx_buffer->map);
|
||||||
|
bus_dmamap_destroy(adapter->txtag, tx_buffer->map);
|
||||||
|
|
||||||
|
m_freem(tx_buffer->m_head);
|
||||||
|
tx_buffer->m_head = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
tx_desc->upper.data = 0;
|
|
||||||
num_avail++;
|
|
||||||
|
|
||||||
if (tx_buffer->m_head) {
|
|
||||||
m_freem(tx_buffer->m_head);
|
|
||||||
tx_buffer->m_head = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++i == adapter->num_tx_desc)
|
if (++i == adapter->num_tx_desc)
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
tx_buffer = &adapter->tx_buffer_area[i];
|
tx_buffer = &adapter->tx_buffer_area[i];
|
||||||
tx_desc = &adapter->tx_desc_base[i];
|
tx_desc = &adapter->tx_desc_base[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter->oldest_used_tx_desc = i;
|
adapter->oldest_used_tx_desc = i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have enough room, clear IFF_OACTIVE to tell the stack
|
* If we have enough room, clear IFF_OACTIVE to tell the stack
|
||||||
@ -2031,41 +2165,51 @@ em_clean_transmit_interrupts(struct adapter * adapter)
|
|||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
static int
|
static int
|
||||||
em_get_buf(int i, struct adapter *adapter,
|
em_get_buf(int i, struct adapter *adapter,
|
||||||
struct mbuf *nmp)
|
struct mbuf *nmp)
|
||||||
{
|
{
|
||||||
register struct mbuf *mp = nmp;
|
register struct mbuf *mp = nmp;
|
||||||
struct ifnet *ifp;
|
struct em_buffer *rx_buffer;
|
||||||
|
struct ifnet *ifp;
|
||||||
|
u_int32_t paddr;
|
||||||
|
int error;
|
||||||
|
|
||||||
ifp = &adapter->interface_data.ac_if;
|
ifp = &adapter->interface_data.ac_if;
|
||||||
|
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
MGETHDR(mp, M_DONTWAIT, MT_DATA);
|
mp = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
adapter->mbuf_alloc_failed++;
|
adapter->mbuf_cluster_failed++;
|
||||||
return(ENOBUFS);
|
return(ENOBUFS);
|
||||||
}
|
}
|
||||||
MCLGET(mp, M_DONTWAIT);
|
mp->m_len = mp->m_pkthdr.len = MCLBYTES;
|
||||||
if ((mp->m_flags & M_EXT) == 0) {
|
} else {
|
||||||
m_freem(mp);
|
mp->m_len = mp->m_pkthdr.len = MCLBYTES;
|
||||||
adapter->mbuf_cluster_failed++;
|
mp->m_data = mp->m_ext.ext_buf;
|
||||||
return(ENOBUFS);
|
mp->m_next = NULL;
|
||||||
}
|
}
|
||||||
mp->m_len = mp->m_pkthdr.len = MCLBYTES;
|
|
||||||
} else {
|
|
||||||
mp->m_len = mp->m_pkthdr.len = MCLBYTES;
|
|
||||||
mp->m_data = mp->m_ext.ext_buf;
|
|
||||||
mp->m_next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ifp->if_mtu <= ETHERMTU) {
|
if (ifp->if_mtu <= ETHERMTU) {
|
||||||
m_adj(mp, ETHER_ALIGN);
|
m_adj(mp, ETHER_ALIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter->rx_buffer_area[i].m_head = mp;
|
|
||||||
adapter->rx_desc_base[i].buffer_addr =
|
|
||||||
vtophys(mtod(mp, vm_offset_t));
|
|
||||||
|
|
||||||
return(0);
|
rx_buffer = &adapter->rx_buffer_area[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using memory from the mbuf cluster pool, invoke the
|
||||||
|
* bus_dma machinery to arrange the memory mapping.
|
||||||
|
*/
|
||||||
|
error = bus_dmamap_load(adapter->rxtag, rx_buffer->map,
|
||||||
|
mtod(mp, void *), mp->m_len,
|
||||||
|
em_dmamap_cb, &paddr, 0);
|
||||||
|
if (error) {
|
||||||
|
m_free(mp);
|
||||||
|
return(error);
|
||||||
|
}
|
||||||
|
rx_buffer->m_head = mp;
|
||||||
|
adapter->rx_desc_base[i].buffer_addr = htole64(paddr);
|
||||||
|
bus_dmamap_sync(adapter->rxtag, rx_buffer->map, BUS_DMASYNC_PREREAD);
|
||||||
|
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
@ -2079,29 +2223,68 @@ em_get_buf(int i, struct adapter *adapter,
|
|||||||
static int
|
static int
|
||||||
em_allocate_receive_structures(struct adapter * adapter)
|
em_allocate_receive_structures(struct adapter * adapter)
|
||||||
{
|
{
|
||||||
int i;
|
int i, error;
|
||||||
|
struct em_buffer *rx_buffer;
|
||||||
|
|
||||||
if (!(adapter->rx_buffer_area =
|
if (!(adapter->rx_buffer_area =
|
||||||
(struct em_buffer *) malloc(sizeof(struct em_buffer) *
|
(struct em_buffer *) malloc(sizeof(struct em_buffer) *
|
||||||
adapter->num_rx_desc, M_DEVBUF,
|
adapter->num_rx_desc, M_DEVBUF,
|
||||||
M_NOWAIT))) {
|
M_NOWAIT))) {
|
||||||
printf("em%d: Unable to allocate rx_buffer memory\n",
|
printf("em%d: Unable to allocate rx_buffer memory\n",
|
||||||
adapter->unit);
|
adapter->unit);
|
||||||
return(ENOMEM);
|
return(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero(adapter->rx_buffer_area,
|
bzero(adapter->rx_buffer_area,
|
||||||
sizeof(struct em_buffer) * adapter->num_rx_desc);
|
sizeof(struct em_buffer) * adapter->num_rx_desc);
|
||||||
|
|
||||||
for (i = 0; i < adapter->num_rx_desc; i++) {
|
error = bus_dma_tag_create(NULL, /* parent */
|
||||||
if (em_get_buf(i, adapter, NULL) == ENOBUFS) {
|
PAGE_SIZE, 0, /* alignment, bounds */
|
||||||
adapter->rx_buffer_area[i].m_head = NULL;
|
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||||
adapter->rx_desc_base[i].buffer_addr = 0;
|
BUS_SPACE_MAXADDR, /* highaddr */
|
||||||
return(ENOBUFS);
|
NULL, NULL, /* filter, filterarg */
|
||||||
}
|
MCLBYTES, /* maxsize */
|
||||||
}
|
1, /* nsegments */
|
||||||
|
MCLBYTES, /* maxsegsize */
|
||||||
|
BUS_DMA_ALLOCNOW, /* flags */
|
||||||
|
&adapter->rxtag);
|
||||||
|
if (error != 0) {
|
||||||
|
printf("em%d: em_allocate_receive_structures: "
|
||||||
|
"bus_dma_tag_create failed; error %u\n",
|
||||||
|
adapter->unit, error);
|
||||||
|
goto fail_0;
|
||||||
|
}
|
||||||
|
|
||||||
return(0);
|
rx_buffer = adapter->rx_buffer_area;
|
||||||
|
for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
|
||||||
|
error = bus_dmamap_create(adapter->rxtag, BUS_DMA_NOWAIT,
|
||||||
|
&rx_buffer->map);
|
||||||
|
if (error != 0) {
|
||||||
|
printf("em%d: em_allocate_receive_structures: "
|
||||||
|
"bus_dmamap_create failed; error %u\n",
|
||||||
|
adapter->unit, error);
|
||||||
|
goto fail_1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < adapter->num_rx_desc; i++) {
|
||||||
|
error = em_get_buf(i, adapter, NULL);
|
||||||
|
if (error != 0) {
|
||||||
|
adapter->rx_buffer_area[i].m_head = NULL;
|
||||||
|
adapter->rx_desc_base[i].buffer_addr = 0;
|
||||||
|
return(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
fail_1:
|
||||||
|
bus_dma_tag_destroy(adapter->rxtag);
|
||||||
|
fail_0:
|
||||||
|
adapter->rxtag = NULL;
|
||||||
|
free(adapter->rx_buffer_area, M_DEVBUF);
|
||||||
|
adapter->rx_buffer_area = NULL;
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
@ -2215,24 +2398,32 @@ em_initialize_receive_unit(struct adapter * adapter)
|
|||||||
static void
|
static void
|
||||||
em_free_receive_structures(struct adapter *adapter)
|
em_free_receive_structures(struct adapter *adapter)
|
||||||
{
|
{
|
||||||
struct em_buffer *rx_buffer;
|
struct em_buffer *rx_buffer;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
INIT_DEBUGOUT("free_receive_structures: begin");
|
INIT_DEBUGOUT("free_receive_structures: begin");
|
||||||
|
|
||||||
if (adapter->rx_buffer_area != NULL) {
|
if (adapter->rx_buffer_area != NULL) {
|
||||||
rx_buffer = adapter->rx_buffer_area;
|
rx_buffer = adapter->rx_buffer_area;
|
||||||
for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
|
for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) {
|
||||||
if (rx_buffer->m_head != NULL)
|
if (rx_buffer->map != NULL) {
|
||||||
m_freem(rx_buffer->m_head);
|
bus_dmamap_unload(adapter->rxtag, rx_buffer->map);
|
||||||
rx_buffer->m_head = NULL;
|
bus_dmamap_destroy(adapter->rxtag, rx_buffer->map);
|
||||||
}
|
}
|
||||||
}
|
if (rx_buffer->m_head != NULL)
|
||||||
if (adapter->rx_buffer_area != NULL) {
|
m_freem(rx_buffer->m_head);
|
||||||
free(adapter->rx_buffer_area, M_DEVBUF);
|
rx_buffer->m_head = NULL;
|
||||||
adapter->rx_buffer_area = NULL;
|
}
|
||||||
}
|
}
|
||||||
return;
|
if (adapter->rx_buffer_area != NULL) {
|
||||||
|
free(adapter->rx_buffer_area, M_DEVBUF);
|
||||||
|
adapter->rx_buffer_area = NULL;
|
||||||
|
}
|
||||||
|
if (adapter->rxtag != NULL) {
|
||||||
|
bus_dma_tag_destroy(adapter->rxtag);
|
||||||
|
adapter->rxtag = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
@ -2255,7 +2446,7 @@ em_process_receive_interrupts(struct adapter * adapter, int count)
|
|||||||
#endif
|
#endif
|
||||||
u_int8_t accept_frame = 0;
|
u_int8_t accept_frame = 0;
|
||||||
u_int8_t eop = 0;
|
u_int8_t eop = 0;
|
||||||
u_int16_t len;
|
u_int16_t len, desc_len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Pointer to the receive descriptor being examined. */
|
/* Pointer to the receive descriptor being examined. */
|
||||||
@ -2275,26 +2466,28 @@ em_process_receive_interrupts(struct adapter * adapter, int count)
|
|||||||
while ((current_desc->status & E1000_RXD_STAT_DD) && (count != 0)) {
|
while ((current_desc->status & E1000_RXD_STAT_DD) && (count != 0)) {
|
||||||
|
|
||||||
mp = adapter->rx_buffer_area[i].m_head;
|
mp = adapter->rx_buffer_area[i].m_head;
|
||||||
|
bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[i].map,
|
||||||
|
BUS_DMASYNC_POSTREAD);
|
||||||
|
|
||||||
accept_frame = 1;
|
accept_frame = 1;
|
||||||
|
desc_len = le16toh(current_desc->length);
|
||||||
if (current_desc->status & E1000_RXD_STAT_EOP) {
|
if (current_desc->status & E1000_RXD_STAT_EOP) {
|
||||||
count--;
|
count--;
|
||||||
eop = 1;
|
eop = 1;
|
||||||
len = current_desc->length - ETHER_CRC_LEN;
|
len = desc_len - ETHER_CRC_LEN;
|
||||||
} else {
|
} else {
|
||||||
eop = 0;
|
eop = 0;
|
||||||
len = current_desc->length;
|
len = desc_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
|
if (current_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
|
||||||
u_int8_t last_byte;
|
u_int8_t last_byte;
|
||||||
u_int32_t pkt_len = current_desc->length;
|
u_int32_t pkt_len = desc_len;
|
||||||
|
|
||||||
if (adapter->fmp != NULL)
|
if (adapter->fmp != NULL)
|
||||||
pkt_len += adapter->fmp->m_pkthdr.len;
|
pkt_len += adapter->fmp->m_pkthdr.len;
|
||||||
|
|
||||||
last_byte = *(mtod(mp, caddr_t) +
|
last_byte = *(mtod(mp, caddr_t) + desc_len - 1);
|
||||||
current_desc->length - 1);
|
|
||||||
|
|
||||||
if (TBI_ACCEPT(&adapter->hw, current_desc->status,
|
if (TBI_ACCEPT(&adapter->hw, current_desc->status,
|
||||||
current_desc->errors,
|
current_desc->errors,
|
||||||
|
@ -71,6 +71,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <machine/clock.h>
|
#include <machine/clock.h>
|
||||||
#include <pci/pcivar.h>
|
#include <pci/pcivar.h>
|
||||||
#include <pci/pcireg.h>
|
#include <pci/pcireg.h>
|
||||||
|
#include <sys/endian.h>
|
||||||
#include "opt_bdg.h"
|
#include "opt_bdg.h"
|
||||||
|
|
||||||
#include <dev/em/if_em_hw.h>
|
#include <dev/em/if_em_hw.h>
|
||||||
@ -242,6 +243,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#define EM_RXBUFFER_8192 8192
|
#define EM_RXBUFFER_8192 8192
|
||||||
#define EM_RXBUFFER_16384 16384
|
#define EM_RXBUFFER_16384 16384
|
||||||
|
|
||||||
|
#define EM_MAX_SCATTER 64
|
||||||
|
|
||||||
#ifdef __alpha__
|
#ifdef __alpha__
|
||||||
#undef vtophys
|
#undef vtophys
|
||||||
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
|
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
|
||||||
@ -264,9 +267,29 @@ typedef struct _em_vendor_info_t {
|
|||||||
|
|
||||||
|
|
||||||
struct em_buffer {
|
struct em_buffer {
|
||||||
struct mbuf *m_head;
|
struct mbuf *m_head;
|
||||||
|
bus_dmamap_t map; /* bus_dma map for packet */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct em_q {
|
||||||
|
bus_dmamap_t map; /* bus_dma map for packet */
|
||||||
|
int nsegs; /* # of segments/descriptors */
|
||||||
|
bus_dma_segment_t segs[EM_MAX_SCATTER];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bus dma allocation structure used by
|
||||||
|
* em_dma_malloc and em_dma_free.
|
||||||
|
*/
|
||||||
|
struct em_dma_alloc {
|
||||||
|
u_int32_t dma_paddr;
|
||||||
|
caddr_t dma_vaddr;
|
||||||
|
bus_dma_tag_t dma_tag;
|
||||||
|
bus_dmamap_t dma_map;
|
||||||
|
bus_dma_segment_t dma_seg;
|
||||||
|
bus_size_t dma_size;
|
||||||
|
int dma_nseg;
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum _XSUM_CONTEXT_T {
|
typedef enum _XSUM_CONTEXT_T {
|
||||||
OFFLOAD_NONE,
|
OFFLOAD_NONE,
|
||||||
@ -316,6 +339,7 @@ struct adapter {
|
|||||||
* The index of the next available descriptor is next_avail_tx_desc.
|
* The index of the next available descriptor is next_avail_tx_desc.
|
||||||
* The number of remaining tx_desc is num_tx_desc_avail.
|
* The number of remaining tx_desc is num_tx_desc_avail.
|
||||||
*/
|
*/
|
||||||
|
struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
|
||||||
struct em_tx_desc *tx_desc_base;
|
struct em_tx_desc *tx_desc_base;
|
||||||
u_int32_t next_avail_tx_desc;
|
u_int32_t next_avail_tx_desc;
|
||||||
u_int32_t oldest_used_tx_desc;
|
u_int32_t oldest_used_tx_desc;
|
||||||
@ -323,6 +347,7 @@ struct adapter {
|
|||||||
u_int16_t num_tx_desc;
|
u_int16_t num_tx_desc;
|
||||||
u_int32_t txd_cmd;
|
u_int32_t txd_cmd;
|
||||||
struct em_buffer *tx_buffer_area;
|
struct em_buffer *tx_buffer_area;
|
||||||
|
bus_dma_tag_t txtag; /* dma tag for tx */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive definitions
|
* Receive definitions
|
||||||
@ -332,11 +357,13 @@ struct adapter {
|
|||||||
* (at rx_buffer_area).
|
* (at rx_buffer_area).
|
||||||
* The next pair to check on receive is at offset next_rx_desc_to_check
|
* 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 em_rx_desc *rx_desc_base;
|
struct em_rx_desc *rx_desc_base;
|
||||||
u_int32_t next_rx_desc_to_check;
|
u_int32_t next_rx_desc_to_check;
|
||||||
u_int16_t num_rx_desc;
|
u_int16_t num_rx_desc;
|
||||||
u_int32_t rx_buffer_len;
|
u_int32_t rx_buffer_len;
|
||||||
struct em_buffer *rx_buffer_area;
|
struct em_buffer *rx_buffer_area;
|
||||||
|
bus_dma_tag_t rxtag;
|
||||||
|
|
||||||
/* Jumbo frame */
|
/* Jumbo frame */
|
||||||
struct mbuf *fmp;
|
struct mbuf *fmp;
|
||||||
@ -350,6 +377,8 @@ struct adapter {
|
|||||||
unsigned long mbuf_cluster_failed;
|
unsigned long mbuf_cluster_failed;
|
||||||
unsigned long no_tx_desc_avail1;
|
unsigned long no_tx_desc_avail1;
|
||||||
unsigned long no_tx_desc_avail2;
|
unsigned long no_tx_desc_avail2;
|
||||||
|
unsigned long no_tx_map_avail;
|
||||||
|
unsigned long no_tx_dma_setup;
|
||||||
u_int64_t tx_fifo_reset;
|
u_int64_t tx_fifo_reset;
|
||||||
u_int64_t tx_fifo_wrk;
|
u_int64_t tx_fifo_wrk;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user