Sync the lem code up with the vlan and other fixes in em.
Delete a unneeded test from the beginning of em_xmit. CRITICAL: shared code fix for 82574, a mutex might not be released, this can cause hangs.
This commit is contained in:
parent
e0a2a85d3a
commit
a4ab528826
@ -666,10 +666,15 @@ static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
|
||||
**/
|
||||
static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_get_hw_semaphore_82574");
|
||||
|
||||
E1000_MUTEX_LOCK(&hw->dev_spec._82571.swflag_mutex);
|
||||
return e1000_get_hw_semaphore_82573(hw);
|
||||
ret_val = e1000_get_hw_semaphore_82573(hw);
|
||||
if (ret_val)
|
||||
E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1765,19 +1765,6 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
|
||||
do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0);
|
||||
ip_off = poff = 0;
|
||||
|
||||
/*
|
||||
** When doing checksum offload, it is critical to
|
||||
** make sure the first mbuf has more than header,
|
||||
** because that routine expects data to be present.
|
||||
*/
|
||||
if ((m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) &&
|
||||
(m_head->m_len < ETHER_HDR_LEN + sizeof(struct ip))) {
|
||||
m_head = m_pullup(m_head, ETHER_HDR_LEN + sizeof(struct ip));
|
||||
*m_headp = m_head;
|
||||
if (m_head == NULL)
|
||||
return (ENOBUFS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Intel recommends entire IP/TCP header length reside in a single
|
||||
* buffer. If multiple descriptors are used to describe the IP and
|
||||
|
@ -51,9 +51,7 @@
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#if __FreeBSD_version >= 700029
|
||||
#include <sys/eventhandler.h>
|
||||
#endif
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
@ -86,8 +84,7 @@
|
||||
/*********************************************************************
|
||||
* Legacy Em Driver version:
|
||||
*********************************************************************/
|
||||
char lem_driver_version[] = "1.0.2";
|
||||
|
||||
char lem_driver_version[] = "1.0.3";
|
||||
|
||||
/*********************************************************************
|
||||
* PCI Device ID Table
|
||||
@ -209,11 +206,9 @@ static void lem_disable_promisc(struct adapter *);
|
||||
static void lem_set_multi(struct adapter *);
|
||||
static void lem_update_link_status(struct adapter *);
|
||||
static int lem_get_buf(struct adapter *, int);
|
||||
#if __FreeBSD_version >= 700029
|
||||
static void lem_register_vlan(void *, struct ifnet *, u16);
|
||||
static void lem_unregister_vlan(void *, struct ifnet *, u16);
|
||||
static void lem_setup_vlan_hw_support(struct adapter *);
|
||||
#endif
|
||||
static int lem_xmit(struct adapter *, struct mbuf **);
|
||||
static void lem_smartspeed(struct adapter *);
|
||||
static int lem_82547_fifo_workaround(struct adapter *, int);
|
||||
@ -231,6 +226,8 @@ static u32 lem_fill_descriptors (bus_addr_t address, u32 length,
|
||||
static int lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
|
||||
static void lem_add_int_delay_sysctl(struct adapter *, const char *,
|
||||
const char *, struct em_int_delay_info *, int, int);
|
||||
static void lem_set_flow_cntrl(struct adapter *, const char *,
|
||||
const char *, int *, int);
|
||||
/* Management and WOL Support */
|
||||
static void lem_init_manageability(struct adapter *);
|
||||
static void lem_release_manageability(struct adapter *);
|
||||
@ -244,11 +241,7 @@ static void lem_led_func(void *, int);
|
||||
#ifdef EM_LEGACY_IRQ
|
||||
static void lem_intr(void *);
|
||||
#else /* FAST IRQ */
|
||||
#if __FreeBSD_version < 700000
|
||||
static void lem_irq_fast(void *);
|
||||
#else
|
||||
static int lem_irq_fast(void *);
|
||||
#endif
|
||||
static void lem_handle_rxtx(void *context, int pending);
|
||||
static void lem_handle_link(void *context, int pending);
|
||||
static void lem_add_rx_process_limit(struct adapter *, const char *,
|
||||
@ -320,14 +313,6 @@ TUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit);
|
||||
static int lem_fc_setting = e1000_fc_full;
|
||||
TUNABLE_INT("hw.em.fc_setting", &lem_fc_setting);
|
||||
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
static u32 lem_shadow_vfta[EM_VFTA_SIZE];
|
||||
|
||||
/* Global used in WOL setup with multiport cards */
|
||||
static int global_quad_port_a = 0;
|
||||
|
||||
@ -462,6 +447,11 @@ lem_attach(device_t dev)
|
||||
lem_rx_process_limit);
|
||||
#endif
|
||||
|
||||
/* Sysctl for setting the interface flow control */
|
||||
lem_set_flow_cntrl(adapter, "flow_control",
|
||||
"max number of rx packets to process",
|
||||
&adapter->fc_setting, lem_fc_setting);
|
||||
|
||||
/*
|
||||
* Validate number of transmit and receive descriptors. It
|
||||
* must not exceed hardware maximum, and must be multiple
|
||||
@ -638,13 +628,11 @@ lem_attach(device_t dev)
|
||||
else
|
||||
adapter->pcix_82544 = FALSE;
|
||||
|
||||
#if __FreeBSD_version >= 700029
|
||||
/* Register for VLAN events */
|
||||
adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
|
||||
lem_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
|
||||
adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
|
||||
lem_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
|
||||
#endif
|
||||
|
||||
lem_add_hw_stats(adapter);
|
||||
|
||||
@ -702,11 +690,7 @@ lem_detach(device_t dev)
|
||||
INIT_DEBUGOUT("em_detach: begin");
|
||||
|
||||
/* Make sure VLANS are not using driver */
|
||||
#if __FreeBSD_version >= 700000
|
||||
if (adapter->ifp->if_vlantrunk != NULL) {
|
||||
#else
|
||||
if (adapter->ifp->if_nvlans != 0) {
|
||||
#endif
|
||||
device_printf(dev,"Vlan in use, detach first\n");
|
||||
return (EBUSY);
|
||||
}
|
||||
@ -730,13 +714,11 @@ lem_detach(device_t dev)
|
||||
EM_TX_UNLOCK(adapter);
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
|
||||
#if __FreeBSD_version >= 700029
|
||||
/* Unregister VLAN events */
|
||||
if (adapter->vlan_attach != NULL)
|
||||
EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
|
||||
if (adapter->vlan_detach != NULL)
|
||||
EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
|
||||
#endif
|
||||
|
||||
ether_ifdetach(adapter->ifp);
|
||||
callout_drain(&adapter->timer);
|
||||
@ -831,6 +813,19 @@ lem_start_locked(struct ifnet *ifp)
|
||||
if (!adapter->link_active)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Force a cleanup if number of TX descriptors
|
||||
* available hits the threshold
|
||||
*/
|
||||
if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
|
||||
lem_txeof(adapter);
|
||||
/* Now do we at least have a minimal? */
|
||||
if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
|
||||
adapter->no_tx_desc_avail1++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
|
||||
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
|
||||
@ -1043,9 +1038,7 @@ lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
}
|
||||
if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
lem_init(adapter);
|
||||
#if __FreeBSD_version >= 700000
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1135,17 +1128,8 @@ lem_init_locked(struct adapter *adapter)
|
||||
/* Setup VLAN support, basic and offload if available */
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
|
||||
|
||||
#if __FreeBSD_version < 700029
|
||||
if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
|
||||
u32 ctrl;
|
||||
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
|
||||
ctrl |= E1000_CTRL_VME;
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
|
||||
}
|
||||
#else
|
||||
/* Use real VLAN Filter support */
|
||||
lem_setup_vlan_hw_support(adapter);
|
||||
#endif
|
||||
|
||||
/* Set hardware offload abilities */
|
||||
ifp->if_hwassist = 0;
|
||||
@ -1174,6 +1158,19 @@ lem_init_locked(struct adapter *adapter)
|
||||
}
|
||||
lem_initialize_receive_unit(adapter);
|
||||
|
||||
/* Use real VLAN Filter support? */
|
||||
if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
|
||||
if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
|
||||
/* Use real VLAN Filter support */
|
||||
lem_setup_vlan_hw_support(adapter);
|
||||
else {
|
||||
u32 ctrl;
|
||||
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
|
||||
ctrl |= E1000_CTRL_VME;
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't lose promiscuous settings */
|
||||
lem_set_promisc(adapter);
|
||||
|
||||
@ -1276,7 +1273,6 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
* Legacy Interrupt Service routine
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static void
|
||||
lem_intr(void *arg)
|
||||
{
|
||||
@ -1311,7 +1307,6 @@ lem_intr(void *arg)
|
||||
}
|
||||
|
||||
EM_TX_LOCK(adapter);
|
||||
lem_txeof(adapter);
|
||||
lem_rxeof(adapter, -1, NULL);
|
||||
lem_txeof(adapter);
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
|
||||
@ -1354,8 +1349,7 @@ lem_handle_rxtx(void *context, int pending)
|
||||
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
if (lem_rxeof(adapter, adapter->rx_process_limit, NULL) != 0)
|
||||
taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
|
||||
lem_rxeof(adapter, adapter->rx_process_limit, NULL);
|
||||
EM_TX_LOCK(adapter);
|
||||
lem_txeof(adapter);
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
@ -1363,7 +1357,8 @@ lem_handle_rxtx(void *context, int pending)
|
||||
EM_TX_UNLOCK(adapter);
|
||||
}
|
||||
|
||||
lem_enable_intr(adapter);
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
lem_enable_intr(adapter);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@ -1371,13 +1366,7 @@ lem_handle_rxtx(void *context, int pending)
|
||||
* Fast Legacy/MSI Combined Interrupt Service routine
|
||||
*
|
||||
*********************************************************************/
|
||||
#if __FreeBSD_version < 700000
|
||||
#define FILTER_STRAY
|
||||
#define FILTER_HANDLED
|
||||
static void
|
||||
#else
|
||||
static int
|
||||
#endif
|
||||
lem_irq_fast(void *arg)
|
||||
{
|
||||
struct adapter *adapter = arg;
|
||||
@ -1550,25 +1539,10 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
|
||||
struct mbuf *m_head;
|
||||
u32 txd_upper, txd_lower, txd_used, txd_saved;
|
||||
int error, nsegs, i, j, first, last = 0;
|
||||
#if __FreeBSD_version < 700000
|
||||
struct m_tag *mtag;
|
||||
#endif
|
||||
|
||||
m_head = *m_headp;
|
||||
txd_upper = txd_lower = txd_used = txd_saved = 0;
|
||||
|
||||
/*
|
||||
* Force a cleanup if number of TX descriptors
|
||||
* available hits the threshold
|
||||
*/
|
||||
if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
|
||||
lem_txeof(adapter);
|
||||
/* Now do we at least have a minimal? */
|
||||
if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
|
||||
adapter->no_tx_desc_avail1++;
|
||||
return (ENOBUFS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** When doing checksum offload, it is critical to
|
||||
** make sure the first mbuf has more than header,
|
||||
@ -1712,20 +1686,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
|
||||
else
|
||||
adapter->num_tx_desc_avail -= nsegs;
|
||||
|
||||
/*
|
||||
** Handle VLAN tag, this is the
|
||||
** biggest difference between
|
||||
** 6.x and 7
|
||||
*/
|
||||
#if __FreeBSD_version < 700000
|
||||
/* Find out if we are in vlan mode. */
|
||||
mtag = VLAN_OUTPUT_TAG(ifp, m_head);
|
||||
if (mtag != NULL) {
|
||||
ctxd->upper.fields.special =
|
||||
htole16(VLAN_TAG_VALUE(mtag));
|
||||
ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
|
||||
}
|
||||
#else /* FreeBSD 7 */
|
||||
if (m_head->m_flags & M_VLANTAG) {
|
||||
/* Set the vlan id. */
|
||||
ctxd->upper.fields.special =
|
||||
@ -1733,7 +1693,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
|
||||
/* Tell hardware to add tag */
|
||||
ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
tx_buffer->m_head = m_head;
|
||||
tx_buffer_mapped->map = tx_buffer->map;
|
||||
@ -2249,11 +2208,7 @@ lem_allocate_irq(struct adapter *adapter)
|
||||
#ifdef EM_LEGACY_IRQ
|
||||
/* We do Legacy setup */
|
||||
if ((error = bus_setup_intr(dev, adapter->res[0],
|
||||
#if __FreeBSD_version > 700000
|
||||
INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
|
||||
#else /* 6.X */
|
||||
INTR_TYPE_NET | INTR_MPSAFE, lem_intr, adapter,
|
||||
#endif
|
||||
&adapter->tag[0])) != 0) {
|
||||
device_printf(dev, "Failed to register interrupt handler");
|
||||
return (error);
|
||||
@ -2270,13 +2225,8 @@ lem_allocate_irq(struct adapter *adapter)
|
||||
taskqueue_thread_enqueue, &adapter->tq);
|
||||
taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
|
||||
device_get_nameunit(adapter->dev));
|
||||
#if __FreeBSD_version < 700000
|
||||
if ((error = bus_setup_intr(dev, adapter->res[0],
|
||||
INTR_TYPE_NET | INTR_FAST, lem_irq_fast, adapter,
|
||||
#else
|
||||
if ((error = bus_setup_intr(dev, adapter->res[0],
|
||||
INTR_TYPE_NET, lem_irq_fast, NULL, adapter,
|
||||
#endif
|
||||
&adapter->tag[0])) != 0) {
|
||||
device_printf(dev, "Failed to register fast interrupt "
|
||||
"handler: %d\n", error);
|
||||
@ -2362,7 +2312,7 @@ lem_hardware_init(struct adapter *adapter)
|
||||
adapter->hw.fc.send_xon = TRUE;
|
||||
|
||||
/* Set Flow control, use the tunable location if sane */
|
||||
if ((lem_fc_setting >= 0) || (lem_fc_setting < 4))
|
||||
if ((lem_fc_setting >= 0) && (lem_fc_setting < 4))
|
||||
adapter->hw.fc.requested_mode = lem_fc_setting;
|
||||
else
|
||||
adapter->hw.fc.requested_mode = e1000_fc_none;
|
||||
@ -2410,14 +2360,8 @@ lem_setup_interface(device_t dev, struct adapter *adapter)
|
||||
ifp->if_capabilities = ifp->if_capenable = 0;
|
||||
|
||||
if (adapter->hw.mac.type >= e1000_82543) {
|
||||
int version_cap;
|
||||
#if __FreeBSD_version < 700000
|
||||
version_cap = IFCAP_HWCSUM;
|
||||
#else
|
||||
version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
|
||||
#endif
|
||||
ifp->if_capabilities |= version_cap;
|
||||
ifp->if_capenable |= version_cap;
|
||||
ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
|
||||
ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2427,6 +2371,16 @@ lem_setup_interface(device_t dev, struct adapter *adapter)
|
||||
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
|
||||
ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
|
||||
|
||||
/*
|
||||
** Dont turn this on by default, if vlans are
|
||||
** created on another pseudo device (eg. lagg)
|
||||
** then vlan events are not passed thru, breaking
|
||||
** operation, but with HW FILTER off it works. If
|
||||
** using vlans directly on the em driver you can
|
||||
** enable this and get full hardware tag filtering.
|
||||
*/
|
||||
ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
ifp->if_capabilities |= IFCAP_POLLING;
|
||||
#endif
|
||||
@ -2551,11 +2505,7 @@ lem_dma_malloc(struct adapter *adapter, bus_size_t size,
|
||||
{
|
||||
int error;
|
||||
|
||||
#if __FreeBSD_version >= 700000
|
||||
error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */
|
||||
#else
|
||||
error = bus_dma_tag_create(NULL, /* parent */
|
||||
#endif
|
||||
EM_DBA_ALIGN, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
@ -2640,21 +2590,17 @@ lem_allocate_transmit_structures(struct adapter *adapter)
|
||||
/*
|
||||
* Create DMA tags for tx descriptors
|
||||
*/
|
||||
#if __FreeBSD_version >= 700000
|
||||
if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
|
||||
#else
|
||||
if ((error = bus_dma_tag_create(NULL, /* parent */
|
||||
#endif
|
||||
1, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
EM_TSO_SIZE, /* maxsize */
|
||||
MCLBYTES * EM_MAX_SCATTER, /* maxsize */
|
||||
EM_MAX_SCATTER, /* nsegments */
|
||||
EM_TSO_SEG_SIZE, /* maxsegsize */
|
||||
MCLBYTES, /* maxsegsize */
|
||||
0, /* flags */
|
||||
NULL, /* lockfunc */
|
||||
NULL, /* lockarg */
|
||||
NULL, /* lockfunc */
|
||||
NULL, /* lockarg */
|
||||
&adapter->txtag)) != 0) {
|
||||
device_printf(dev, "Unable to allocate TX DMA tag\n");
|
||||
goto fail;
|
||||
@ -3072,23 +3018,20 @@ lem_txeof(struct adapter *adapter)
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
|
||||
adapter->next_tx_to_clean = first;
|
||||
adapter->num_tx_desc_avail = num_avail;
|
||||
|
||||
/*
|
||||
* If we have enough room, clear IFF_DRV_OACTIVE to
|
||||
* tell the stack that it is OK to send packets.
|
||||
* If there are no pending descriptors, clear the watchdog.
|
||||
*/
|
||||
if (num_avail > EM_TX_CLEANUP_THRESHOLD) {
|
||||
if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
if (num_avail == adapter->num_tx_desc) {
|
||||
if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
|
||||
adapter->watchdog_check = FALSE;
|
||||
adapter->num_tx_desc_avail = num_avail;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
adapter->num_tx_desc_avail = num_avail;
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@ -3185,11 +3128,7 @@ lem_allocate_receive_structures(struct adapter *adapter)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 700000
|
||||
error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
|
||||
#else
|
||||
error = bus_dma_tag_create(NULL, /* parent */
|
||||
#endif
|
||||
1, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
@ -3459,7 +3398,7 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
{
|
||||
struct ifnet *ifp = adapter->ifp;;
|
||||
struct mbuf *mp;
|
||||
u8 status, accept_frame = 0, eop = 0;
|
||||
u8 status = 0, accept_frame = 0, eop = 0;
|
||||
u16 len, desc_len, prev_len_adj;
|
||||
int i, rx_sent = 0;
|
||||
struct e1000_rx_desc *current_desc;
|
||||
@ -3477,11 +3416,13 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
while ((current_desc->status & E1000_RXD_STAT_DD) &&
|
||||
(count != 0) &&
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
while (count != 0 && ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
struct mbuf *m = NULL;
|
||||
|
||||
status = current_desc->status;
|
||||
if ((status & E1000_RXD_STAT_DD) == 0)
|
||||
break;
|
||||
|
||||
mp = adapter->rx_buffer_area[i].m_head;
|
||||
/*
|
||||
* Can't defer bus_dmamap_sync(9) because TBI_ACCEPT
|
||||
@ -3493,7 +3434,6 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
accept_frame = 1;
|
||||
prev_len_adj = 0;
|
||||
desc_len = le16toh(current_desc->length);
|
||||
status = current_desc->status;
|
||||
if (status & E1000_RXD_STAT_EOP) {
|
||||
count--;
|
||||
eop = 1;
|
||||
@ -3571,16 +3511,10 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
goto skip;
|
||||
#endif
|
||||
if (status & E1000_RXD_STAT_VP) {
|
||||
#if __FreeBSD_version < 700000
|
||||
VLAN_INPUT_TAG_NEW(ifp, adapter->fmp,
|
||||
(le16toh(current_desc->special) &
|
||||
E1000_RXD_SPC_VLAN_MASK));
|
||||
#else
|
||||
adapter->fmp->m_pkthdr.ether_vtag =
|
||||
(le16toh(current_desc->special) &
|
||||
E1000_RXD_SPC_VLAN_MASK);
|
||||
adapter->fmp->m_flags |= M_VLANTAG;
|
||||
#endif
|
||||
}
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
skip:
|
||||
@ -3636,7 +3570,7 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
if (done != NULL)
|
||||
*done = rx_sent;
|
||||
EM_RX_UNLOCK(adapter);
|
||||
return (current_desc->status & E1000_RXD_STAT_DD);
|
||||
return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
@ -3728,7 +3662,6 @@ lem_receive_checksum(struct adapter *adapter,
|
||||
}
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 700029
|
||||
/*
|
||||
* This routine is run via an vlan
|
||||
* config EVENT
|
||||
@ -3745,12 +3678,15 @@ lem_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
|
||||
if ((vtag == 0) || (vtag > 4095)) /* Invalid ID */
|
||||
return;
|
||||
|
||||
EM_CORE_LOCK(adapter);
|
||||
index = (vtag >> 5) & 0x7F;
|
||||
bit = vtag & 0x1F;
|
||||
lem_shadow_vfta[index] |= (1 << bit);
|
||||
adapter->shadow_vfta[index] |= (1 << bit);
|
||||
++adapter->num_vlans;
|
||||
/* Re-init to load the changes */
|
||||
lem_init(adapter);
|
||||
if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
|
||||
lem_init_locked(adapter);
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3769,12 +3705,15 @@ lem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
|
||||
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
|
||||
return;
|
||||
|
||||
EM_CORE_LOCK(adapter);
|
||||
index = (vtag >> 5) & 0x7F;
|
||||
bit = vtag & 0x1F;
|
||||
lem_shadow_vfta[index] &= ~(1 << bit);
|
||||
adapter->shadow_vfta[index] &= ~(1 << bit);
|
||||
--adapter->num_vlans;
|
||||
/* Re-init to load the changes */
|
||||
lem_init(adapter);
|
||||
if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
|
||||
lem_init_locked(adapter);
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3797,9 +3736,9 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
|
||||
** we need to repopulate it now.
|
||||
*/
|
||||
for (int i = 0; i < EM_VFTA_SIZE; i++)
|
||||
if (lem_shadow_vfta[i] != 0)
|
||||
if (adapter->shadow_vfta[i] != 0)
|
||||
E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
|
||||
i, lem_shadow_vfta[i]);
|
||||
i, adapter->shadow_vfta[i]);
|
||||
|
||||
reg = E1000_READ_REG(hw, E1000_CTRL);
|
||||
reg |= E1000_CTRL_VME;
|
||||
@ -3815,7 +3754,6 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
|
||||
adapter->max_frame_size + VLAN_TAG_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
lem_enable_intr(struct adapter *adapter)
|
||||
@ -4661,6 +4599,16 @@ lem_add_int_delay_sysctl(struct adapter *adapter, const char *name,
|
||||
info, 0, lem_sysctl_int_delay, "I", description);
|
||||
}
|
||||
|
||||
static void
|
||||
lem_set_flow_cntrl(struct adapter *adapter, const char *name,
|
||||
const char *description, int *limit, int value)
|
||||
{
|
||||
*limit = value;
|
||||
SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
|
||||
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
|
||||
}
|
||||
|
||||
#ifndef EM_LEGACY_IRQ
|
||||
static void
|
||||
lem_add_rx_process_limit(struct adapter *adapter, const char *name,
|
||||
@ -4672,5 +4620,3 @@ lem_add_rx_process_limit(struct adapter *adapter, const char *name,
|
||||
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -328,11 +328,9 @@ struct adapter {
|
||||
struct task tx_task;
|
||||
struct taskqueue *tq; /* private task queue */
|
||||
|
||||
#if __FreeBSD_version >= 700029
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
u32 num_vlans;
|
||||
#endif
|
||||
|
||||
/* Management and WOL features */
|
||||
u32 wol;
|
||||
@ -341,11 +339,22 @@ struct adapter {
|
||||
|
||||
/* Multicast array memory */
|
||||
u8 *mta;
|
||||
/* Info about the board itself */
|
||||
|
||||
/*
|
||||
** 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;
|
||||
@ -407,6 +416,9 @@ struct adapter {
|
||||
unsigned long no_tx_dma_setup;
|
||||
unsigned long watchdog_events;
|
||||
unsigned long rx_overruns;
|
||||
unsigned long rx_irq;
|
||||
unsigned long tx_irq;
|
||||
unsigned long link_irq;
|
||||
|
||||
/* 82547 workaround */
|
||||
uint32_t tx_fifo_size;
|
||||
|
Loading…
Reference in New Issue
Block a user